使用 pandas dataframe.query() 选择列

Posted

技术标签:

【中文标题】使用 pandas dataframe.query() 选择列【英文标题】:Select columns using pandas dataframe.query() 【发布时间】:2017-11-20 12:01:54 【问题描述】:

dataframe.query() 上的文档非常 简洁 http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.query.html。我也无法通过网络搜索找到投影示例。

所以我尝试简单地提供列名:这给出了语法错误。同样,输入select,然后输入列名。那么..如何做到这一点?

【问题讨论】:

我觉得这个问题很清楚。 @DaniSpringer 代码不是每个问题都需要。 【参考方案1】:

在玩了一段时间并通过the source code 阅读DataFrame.query 之后,我想不出办法。

如果不是不可能的话,显然至少强烈反对。当这个问题出现在 github 上时,多产的 Pandas dev/maintainer jreback suggested using df.eval() for selecting columns and df.query() for filtering on rows。


更新:

javadba 指出eval 的返回值不是数据帧。例如,进一步充实 jreback 的示例......

df.eval('A')

返回 Pandas 系列,但是

df.eval(['A', 'B'])

不返回 DataFrame,它返回一个列表(熊猫系列)。

因此,最终保持对行和列进行过滤的灵活性的最佳方法似乎是使用iloc/loc,例如

df.loc[0:4, ['A', 'C']]

输出

          A         C
0 -0.497163 -0.046484
1  1.331614  0.741711
2  1.046903 -2.511548
3  0.314644 -0.526187
4 -0.061883 -0.615978

【讨论】:

eval 不返回 DataFrame .. ret : ndarray, scalar, or pandas object 。无论如何都赞成这项努力。 嗯,好点。刚试过iris2 = iris.eval(['sepal_length', 'species']),但我回来的iris2list...每个元素都是Pandas Series。很奇怪。 看起来我们回到了iloc/loc。也许玩一下,我可以在这里奖励。 更新了我的答案。不认为这是一个特别令人满意的答案,但认为这是答案。 我在性能不重要时使用它,并且更喜欢使用 postgres 后端,因为它支持分析/窗口功能。实际上和几年前一样。我经常做的另一种方法是使用 spark sql【参考方案2】:

Dataframe.query 更像是 SQL 语句中的 where 子句,而不是 select 部分

import pandas as pd
import numpy as np
np.random.seed(123)
dates = pd.date_range('1/1/2000', periods=8)
df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])

要选择一列或多列,您可以使用以下命令:

df['A'] or df.loc[:,'A']

df[['A','B']] or df.loc[:,['A','B']]

要使用.query 方法,你可以这样做

df.query('A > B') 将返回 A 列中的值大于 b 列中的值的所有行。

                   A         B         C         D
2000-01-03  1.265936 -0.866740 -0.678886 -0.094709
2000-01-04  1.491390 -0.638902 -0.443982 -0.434351
2000-01-05  2.205930  2.186786  1.004054  0.386186
2000-01-08 -0.140069 -0.861755 -0.255619 -2.798589

在我看来,布尔索引选择更易读

df[df['A'] > df['B']]

【讨论】:

【参考方案3】:

pandasql

https://pypi.python.org/pypi/pandasql/0.1.0

这是来自以下博客http://blog.yhat.com/posts/pandasql-sql-for-pandas-dataframes.html 的示例。输入是两个 DataFrames meatbirths :这种方法给出了 sql 预期的 projectionsfilteringaggregationsorting

@maxpower 确实提到这个包有问题:所以让我们看看.. 至少博客中的代码和下面显示的代码可以正常工作。

pysqldf = lambda q: sqldf(q, globals())

q  = """
SELECT
  m.date
  , m.beef
  , b.births
FROM
  meat m
LEFT JOIN
  births b
    ON m.date = b.date
WHERE
    m.date > '1974-12-31';
"""

meat = load_meat()
births = load_births()

df = pysqldf(q)

根据需要,输出是熊猫DataFrame

它非常适合我的特定用例(评估我们的罪行)

odf = pysqldf("select %s from df where sweapons > 10 order by sweapons desc limit 10" %scols)
p('odf\n', odf)

 odf
:    SMURDER  SRAPE  SROBBERY  SAGASSLT  SOTHASLT  SVANDLSM  SWEAPONS
0        0      0         0         1         1        10        54
1        0      0         0         0         1         0        52
2        0      0         0         0         1         0        46
3        0      0         0         0         1         0        43
4        0      0         0         0         1         0        33
5        1      0         2        16        28         4        32
6        0      0         0         7        17         4        30
7        0      0         0         0         1         0        29
8        0      0         0         7        16         3        29
9        0      0         0         1         0         5        28

更新我现在用pandasql 做了很多事情:计算字段、限制、别名、级联数据帧.. 它只是如此富有成效。 p>

另一个更新(3 年后) 这有效,但警告它是 非常 慢(秒 vs 毫秒)-

【讨论】:

很高兴这对您的情况非常有效。我有几次对此感到沮丧,但也许这是因为我没有为修复它做出贡献。这是我遇到的最后一个错误 - select from multiple tables 不起作用。这是一种耻辱,因为这种操作在 SQL 中比在基本 pandas 中读起来好得多。我还担心,由于这个问题已经开放了大约 18 个月,并且没有人甚至标签分配给它,所以图书馆可能没有得到很好的维护。 @MaxPower 我现在正在使用postgresql 方言和pandasql - 而不是默认和有限的sqlite。到目前为止效果更好。【参考方案4】:

怎么样

df_new = df.query('col1==1 & col2=="x" ')[['col1', 'col3']]

将过滤 col1 等于 1 且 col2 等于“X”的行并仅返回第 1 列和第 3 列。

但是您需要过滤行,否则它不起作用。

对于过滤列,最好使用.loc.iloc

【讨论】:

【参考方案5】:

只是一个更简单的示例解决方案(使用get):

我的目标:

我希望查询结果中的 latlon 列。

我的餐桌详情:

df_city.columns

Index(['name', 'city_id', 'lat', 'lon', 'CountryName', 'ContinentName'], dtype='object')

# All columns
city_continent = df_city.get(df_city['ContinentName']=='Oceania')

# Only lat and lon
city_continent[['lat', 'lon']]
  lat lon
113883    -19.12753   -169.84623
113884    -19.11667   -169.90000
113885    -19.10000   -169.91667
113886    -46.33333   168.85000
113887    -46.36667   168.55000
...   ... ...
347956    -23.14083   113.77630
347957    -31.48023   131.84242
347958    -28.29967   153.30142
347959    -35.60358   138.10548
347960    -35.02852   117.83416
3712 rows × 2 columns

【讨论】:

以上是关于使用 pandas dataframe.query() 选择列的主要内容,如果未能解决你的问题,请参考以下文章

pandas-query使用

是否可以使用 DataFrame.query() 来判断列是否存在?

pandas 常见函数的使用

为啥我使用 modin.pandas 比使用 Pandas 需要更长的时间 [ray]

为啥使用numpy和pandas来进行数据处理?

Pandas的使用---Pandas的数据结构