我想根据掩码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"] <= 10)
hr = df["hr"][idx]
timestamps = df["timestamp"][idx]
答案 0 :(得分:4)
关键点是:
pd.DataFrame.iloc
主要用于基于位置的整数索引。pd.DataFrame.loc
最常用于标签或布尔数组。df[x][y]
,是explicitly discouraged,永远不需要。idx.values
返回numpy
系列的idx
数组表示。这不能提供.iloc
,也无需提供.loc
,这可以直接idx
。下面是两个可行的例子。在任一示例中,您都可以使用类似的语法来屏蔽数据框或系列。例如,df['hr'].loc[mask]
和df.loc[mask]
一样有效。
这里我们使用numpy.where
来提取布尔系列中True
元素的整数索引。 iloc
确实接受布尔数组,但在我看来,这不太清楚; “i”代表整数。
idx = (df['timestamp'] >= 5) & (df['timestamp'] <= 10)
mask = np.where(idx)[0]
df = df.iloc[mask]
当我们已经通过特定系列查询时,使用loc
更自然。
mask = (df['timestamp'] >= 5) & (df['timestamp'] <= 10)
df = df.loc[mask]
loc
访问者并使用df[mask]
。df.loc[mask, 'col_name']
Indexing and Selecting Data是pandas
的基础:阅读官方文档是无可替代的。
答案 1 :(得分:2)
不要混合基于__getitem__
的索引和(i)基于loc的。使用其中一个。我更喜欢(i)通过索引访问时的loc,以及当您按列访问或使用布尔索引时__getitem__
。
以下是一些常见的索引编制方法及其相应的更正。
df.iloc[idx].loc[:, column]
df.iloc[idx][column]
df[column][idx]
df[column].iloc[idx]
当您尝试分配这些解决方案时,大多数这些解决方案都会导致管道问题(主要是以SettingWithCopyWarning的形式),因为这些解决方案会创建视图并与他们正在查看的原始DataFrame绑定。
所有这些版本的正确解决方案是df.iloc[idx, df.columns.get_loc(column)]
请注意idx
是一个整数索引数组,column
是一个字符串标签。同样适用于loc
。
如果您有一系列布尔值,请改用loc
,如下所示:df.loc[boolean_idx, column]
此外,这些都很好:df[column]
和df[boolean_mask]
有索引单行或单列的规则。根据它的完成方式,您将获得Series或DataFrame。因此,如果要将DataFrame df
中的第100行索引为DataFrame切片,则需要执行以下操作:
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)]