【问题标题】:Best way to subset a pandas dataframe [closed]对熊猫数据框进行子集化的最佳方法[关闭]
【发布时间】:2018-06-30 10:36:59
【问题描述】:

嘿,我是 Pandas 的新手,刚刚遇到df.query()

当您可以使用括号表示法直接过滤您的数据框时,为什么人们会使用df.query()?官方的 pandas 教程似乎也更喜欢后一种方法。

用括号表示:

df[df['age'] <= 21]

用pandas查询方法:

df.query('age <= 21')

除了已经提到的一些风格或灵活性差异之外,还有一个典型的首选 - 即在大型数据帧上执行操作?

【问题讨论】:

  • 因为有些人不能轻易地构造出正确的过滤和聚合,但是会写SQL之类的东西?
  • 因为您可能想要使用从用户获得的查询或从文件中读取的查询,或以某种方式以编程方式生成的查询。
  • 当它们首次发布时,由于 numexpr,它们获得了一些性能优势,但我不认为它们现在的性能优于布尔索引。

标签: python pandas dataframe data-science


【解决方案1】:

考虑以下示例 DF:

In [307]: df
Out[307]:
  sex  age     name
0   M   40      Max
1   F   35     Anna
2   M   29      Joe
3   F   18    Maria
4   F   23  Natalie

有很多理由更喜欢.query() 方法。

  • 与布尔索引相比,它可能更短更简洁:

    In [308]: df.query("20 <= age <= 30 and sex=='F'")
    Out[308]:
      sex  age     name
    4   F   23  Natalie
    
    In [309]: df[(df['age']>=20) & (df['age']<=30) & (df['sex']=='F')]
    Out[309]:
      sex  age     name
    4   F   23  Natalie
    
  • 您可以以编程方式准备条件(查询):

    In [315]: conditions = {'name':'Joe', 'sex':'M'}
    
    In [316]: q = ' and '.join(['{}=="{}"'.format(k,v) for k,v in conditions.items()])
    
    In [317]: q
    Out[317]: 'name=="Joe" and sex=="M"'
    
    In [318]: df.query(q)
    Out[318]:
      sex  age name
    2   M   29  Joe
    

PS也有一些缺点:

  • 我们不能对包含空格的列或仅由数字组成的列使用.query() 方法
  • 并非所有功能都可以应用,或者在某些情况下我们必须使用engine='python' 而不是默认的engine='numexpr'(这样更快)

注意:Jeff(Pandas 主要贡献者之一,Pandas 核心团队成员)once said

请注意,实际上 .query 只是一个不错的接口,事实上 它有非常具体的保证,这意味着它的意思是像 查询语言,而不是完全通用的界面。

【讨论】:

  • 也许这里也值得注意Jeff's comment:“请注意,实际上 .query 只是一个不错的接口,实际上它有非常具体的保证,这意味着它的意思是解析一种查询语言,而不是一个完全通用的界面。”
  • @ayhan,好点子-谢谢!我会把它添加到答案中
【解决方案2】:

documentation 中的一些其他有趣的用法。

Reuseable

query() 的一个用例是 当你有一个 DataFrame 的集合时 具有列名称(或索引级别/名称)子集的对象 常见的。 您可以将相同的查询传递给两个框架,而无需 指定您有兴趣查询的框架 -- (Source)

例子:

dfA = pd.DataFrame([[1,2,3], [4,5,6]], columns=["X", "Y", "Z"])
dfB = pd.DataFrame([[1,3,3], [4,1,6]], columns=["X", "Y", "Z"])
q = "(X > 3) & (Y < 10)"

print(dfA.query(q))
print(dfB.query(q))

   X  Y  Z
1  4  5  6
   X  Y  Z
1  4  1  6

More flexible syntax

df.query('a < b and b < c')  # understand a bit more English

Support in operator and not in (alternative to isin)

df.query('a in [3, 4, 5]') # select rows whose value of column a is in [2, 3, 4]

Special usage of == and != (similar to in/not in)

df.query('a == [1, 3, 5]') # select whose value of column a is in [1, 3, 5]
# equivalent to df.query('a in [1, 3, 5]')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 2021-08-16
    • 2022-11-18
    • 1970-01-01
    相关资源
    最近更新 更多