Pandas,用于布尔索引的 loc 与非 loc
Posted
技术标签:
【中文标题】Pandas,用于布尔索引的 loc 与非 loc【英文标题】:Pandas, loc vs non loc for boolean indexing 【发布时间】:2019-04-17 05:43:42 【问题描述】:我所做的所有研究都指向使用 loc
作为通过 col(s) 值过滤数据帧的方法,今天我正在阅读 this 并通过我测试的示例发现 @ 987654325@ 按其值过滤 cols 时并不真正需要:
前:
df = pd.DataFrame(np.arange(0, 20, 0.5).reshape(8, 5), columns=['a', 'b', 'c', 'd', 'e'])
df.loc[df['a'] >= 15]
a b c d e
6 15.0 15.5 16.0 16.5 17.0
7 17.5 18.0 18.5 19.0 19.5
df[df['a'] >= 15]
a b c d e
6 15.0 15.5 16.0 16.5 17.0
7 17.5 18.0 18.5 19.0 19.5
注意:我知道loc
或iloc
按其索引和位置返回行。我不是根据这个功能进行比较的。
但是在过滤的时候,做“where
”子句的时候用loc
和不用loc
有什么区别呢?如果有的话。为什么我遇到的关于这个主题的所有例子都使用loc
?
【问题讨论】:
在这种情况下,你是对的。对于简单的过滤,将布尔数组作为df.loc[]
或直接传递给df[]
没有区别。当您需要特定的行和列时,强大的功能或 .loc[]
来自更复杂的查找。它的语法也比将多个布尔条件链接在一起更灵活、更通用、更不容易出错。总体而言,它可以更强大地访问/过滤您的 df 中的数据。
@cvonsteg,作为扩展,您会说df[df.columns[::-1]]
与df.iloc[:, ::-1]
相同(即只是语法糖或O(1) 性能差异)吗?因为那个doesn't seem to be the case。就我个人而言,我觉得这很令人困惑,似乎没有任何关于 __getitem__
做什么以及何时/如何做的官方文档。
@jpp 完全免责声明 - 我没有研究过这个,所以以下只是猜测。对于大型数据集,我想您可能会看到两种方法之间的分歧,倾向于 .iloc[]。这完全基于 df[df.columns[]] 对 df 执行多个操作(创建 Index 对象,然后是 __getitem__
)的概念,而 .iloc[] 可能是对此的优化方法(也许调用生成器,一些沿着这些路线?)。但你说得对,Data Model 文档非常少。
【参考方案1】:
根据文档,loc
接受一个布尔数组来选择行,在你的情况下
>>> df['a'] >= 15
>>>
0 False
1 False
2 False
3 False
4 False
5 False
6 True
7 True
Name: a, dtype: bool
被视为布尔数组。
pandas
的作者 Wes McKinney 认为,您可以在此处省略 loc
并发出 df[df['a'] >= 15]
是一种特殊情况的便利。
直接从他的书中引用,Python for Data Analysis,p。 144、df[val]
用于...
从 DataFrame 中选择单列或列序列; 特殊情况 便利性:布尔数组(过滤行)、切片(切片行)或布尔数据帧 (根据某些标准设置值)
【讨论】:
pd.DataFrame.__getitem__
和 pd.Series.__getitem__
似乎没有记录布尔索引。当然,文档中存在很多df[col_name]
的情况。所以可能我们甚至不应该依赖逐行索引而总是使用loc
?
@jpp 使用loc
可能会更明确一点。就个人而言,我想坚持便利功能。我怀疑开发人员会在这一点上把它拿走。
我同意你的观点。但我还要说,在一般情况下,性能不总是相同的。例如,df[df.columns[::-1]]
的性能可能比df.iloc[:, ::-1]
差得多。我希望有更多关于 __getitem__
的建议,因为它(正如你所指出的)对于人们如何使用 Pandas 非常重要。以上是关于Pandas,用于布尔索引的 loc 与非 loc的主要内容,如果未能解决你的问题,请参考以下文章