Python 熊猫索引的最佳实践
我想根据掩码选择行,Python 熊猫索引的最佳实践,python,pandas,dataframe,indexing,series,Python,Pandas,Dataframe,Indexing,Series,我想根据掩码选择行,idx。我可以想到两种不同的可能性,要么使用iloc,要么只使用括号。我已经在下面展示了两种可能性(在数据帧df)。它们是否同样可行 idx = (df["timestamp"] >= 5) & (df["timestamp"] <= 10) idx = idx.values hr = df["hr"].iloc[idx] timestamps = df["timestamp"].iloc[idx] idx=(df[“timestamp”]>=5)和(d
idx
。我可以想到两种不同的可能性,要么使用iloc
,要么只使用括号。我已经在下面展示了两种可能性(在数据帧df
)。它们是否同样可行
idx = (df["timestamp"] >= 5) & (df["timestamp"] <= 10)
idx = idx.values
hr = df["hr"].iloc[idx]
timestamps = df["timestamp"].iloc[idx]
idx=(df[“timestamp”]>=5)和(df[“timestamp”]=5)和(df[“timestamp”]不,它们不一样。一个使用直接语法,而另一个依赖链接索引
关键点是:
- 主要用于基于整数位置的索引
- 最常用于标签或布尔数组
- 链式索引,即通过
df[x][y]
,是而且从来都不是必需的
idx.values
返回idx
系列的numpy
数组表示形式。这不能馈送.iloc
,也不需要馈送.loc
,后者可以直接获取idx
下面是两个可行的示例。在这两个示例中,您都可以使用类似的语法来屏蔽数据帧或序列。例如,df['hr'].loc[mask]
与df.loc[mask]
一样有效
伊洛克
这里我们使用numpy。其中
提取布尔序列中True
元素的整数索引。iloc
确实接受布尔数组,但在我看来,这不太清楚;“i”代表整数
idx = (df['timestamp'] >= 5) & (df['timestamp'] <= 10)
mask = np.where(idx)[0]
df = df.iloc[mask]
- 当仅屏蔽行时,您可以完全省略
loc
访问器,并使用df[mask]
- 如果按行屏蔽并对列进行过滤,则可以使用
df.loc[mask,'col_name']
是熊猫的基础:阅读官方文档是无可替代的。不要将基于\uuuuu getitem\uuuuu
的索引和(i)基于loc的索引混合使用。使用其中一种。我更喜欢(i)通过索引访问时使用loc,以及通过列或布尔索引访问时使用\uuu getitem\uuuu
以下是一些通常不好的索引方法:
df.loc[idx].loc[:, col]
df.loc[idx][col]
df[column][idx]
df[column].loc[idx]
所有上述操作的正确方法是df.loc[idx,col]
。如果idx
是一个整数标签,请使用df.loc[df.index[idx,col]
当您尝试分配给这些解决方案时,大多数解决方案都会导致问题(主要是以SettingWithCopyWarning的形式),因为这些解决方案会创建视图并绑定到它们查看的原始数据帧
所有这些版本的正确解决方案是df.iloc[idx,df.columns.get_loc(column)]
请注意,idx
是一个整数索引数组,column
是一个字符串标签。类似地,对于loc
如果您有一个布尔数组,请改用loc
,如下所示:df.loc[boolean_idx,column]
此外,这些都很好:df[column]
,和df[boolean\u mask]
为单行或单列编制索引有一些规则。根据其编制方式,您将获得一个系列或数据帧。因此,如果要将数据帧df
中的第100行作为数据帧切片编制索引,则需要执行以下操作:
df.iloc[[100], :] # `:` selects every column
而不是
df.iloc[100, :]
对于基于列的索引也是如此
最后,如果要索引单个标量,请使用at
或iat
OTOH,根据您的要求,我建议第三种选择:
ts = df.loc[df.timestamp.between(5, 10), 'timestamp']
或者如果你是整个事情的子集
df = df[df.timestamp.between(5, 10)]
您的问题归结为是使用df['col'].iloc[idx]
还是仅使用[idx]
,其中idx
是布尔向量(不是int)。所以你只是问布尔掩码的情况。当谈论熊猫索引时,从哪里开始。也许文档是一个好的开始。永远不要像这样混合和链接索引操作。你会受到伤害。我已经将你问题的标题编辑成我相信很多人都会搜索的内容.让我看看。顺便问一下,你介意养成一种习惯,对你认为有用的答案进行投票/接受吗?这对社区很有帮助,我注意到你似乎并不经常这样做。是否使用mask=idx.values而不是mask=np.where(idx)[0]不起作用?不,它不起作用。因为idx.values
只会给出一个布尔数组,它不能根据提供给.iloc
。iloc主要基于整数位置(从轴的0到长度-1),但也可以与布尔数组一起使用“iloc只能接受一个numpy数组,但不能接受该系列,否则我会得到一个错误neccessary@machinery,没错,我不想在这里复制这些文档(那里有更多可用的文档)。但我又更新了:)。@BenMares那里的措辞似乎不好。我本想在不正确的方法旁边添加注释中的更正,但后来意识到所有这些都是错误地编写同一表达式的不同方式。在这里见我的朋友。
ts = df.loc[df.timestamp.between(5, 10), 'timestamp']
df = df[df.timestamp.between(5, 10)]