【问题标题】:pandas: iterative filtering a DataFrame's rowspandas:迭代过滤 DataFrame 的行
【发布时间】:2013-09-02 11:34:57
【问题描述】:

假设我有一个像这样的DataFrame

df = pd.DataFrame([['x', 1, 2], ['x', 1, 3], ['y', 2, 2]], 
                  columns=['a', 'b', 'c'])

要选择c == 2a == 'x' 所在的所有行,我可以这样做,

df[(df['a'] == 'x') & (df['c'] == 2)]

或者我可以通过制作临时变量来迭代优化,

df1 = df[df['a'] == 'x']
df2 = df1[df1['c'] == 2]

有没有办法对行进行迭代优化?

(
  df
  .refine(lambda row: row['a'] == 'x')     # this method doesn't exist
  .refine(lambda row: row['c'] == 2)
)

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    虽然目前这不是解决方案,但在 pandas 0.13 版中您将能够做到

    df.query('a == "x"').query('c == 2')
    

    实现你想要的。

    你也可以这样做

    df['a == "x"']['c == 2']
    

    df['a == "x" and c == 2']
    

    怎么了

    df[(df.a == 'x') & (df.c == 2)]
    

    直到 0.13?

    【讨论】:

    • @AndyHayden 不,如果我理解正确的话。在链接的情况下,您将调用query 的次数与链接的次数一样多。我认为没有一种理智的方法可以将链变成[]中表达式的“and-ing”
    • 这只是一种风格偏好。方法链使我的代码更清晰。 pandas 0.13 是否允许我过滤行的任意函数,而不是通过 DataFrame.query 语法对单个列进行简单比较?
    • 可能不会。现在函数调用没有在解析器中实现。 query 使用不支持任意函数调用的numexpr 为大数组(> 10000 个元素)产生很大的加速(它支持一些numpy 数学函数和where IIRC)。其他后端可以支持任意可调用对象,但这似乎不值得仅仅为了样式,尽管一旦核心query 代码被合并,我可以说服我实现它。或者,可以添加DataFrames 上的方法来执行您想要的操作(链式选择),但这似乎天生就很慢。
    • @AndyHayden 听起来你在谈论惰性评估,这是一个比eval/query 更广泛的话题。我正在查看filter 方法,想知道DataFrame content (而不是轴)的类似方法是否有用。我不会反对refine...
    • @PhillipCloud 这正是昨晚让我难以理解的短语。肯定是非常广泛的话题。不确定我是否关注内容与轴。
    【解决方案2】:

    如果您有多个术语;直到运行时您才知道的数量,您可以执行以下操作。我并不是说这是实现目标的绝妙方式,但我看不到 Pandas 0.14.1 的替代方案:

    df = pd.DataFrame([['x', 1, 2], ['x', 1, 3], ['y', 2, 2]],
                      columns=['a', 'b', 'c'])
    
    conditions = {'a': 'x', 'c': 2}
    
    def esc(term):
        if isinstance(term, str):
            return '"%s"' % term
        return str(term)
    
    q_parts = ["%s == %s" % (k, esc(v)) for k, v in conditions.items()]
    q = ' and '.join(q_parts)
    
    print df.query(q)
    

    当然,esc 函数或更宽的 sn-p 需要进一步扩展以处理逻辑非,is x in (x, y, z) 等...

    【讨论】:

      猜你喜欢
      • 2018-03-23
      • 2018-08-03
      • 2018-11-09
      • 2021-11-26
      • 2020-01-03
      • 2021-12-28
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多