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

注意:我知道lociloc 按其索引和位置返回行。我不是根据这个功能进行比较的。

但是在过滤的时候,做“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的主要内容,如果未能解决你的问题,请参考以下文章

004.pandas.DataFrame

004.pandas.DataFrame

pandas数据框loc属性语法及示例

Pandas经典用法:数据筛选之iloc和loc

求教pandas的dataframe索引值只有一行,用loc如何不返回series

Pandas Dataframe .loc + 更新非唯一日期时间索引?