【问题标题】:GroupBy functions in Python Pandas like SUM(col_1*col_2), weighted average etcPython Pandas 中的 GroupBy 函数,如 SUM(col_1*col_2)、加权平均等
【发布时间】:2012-04-18 01:31:35
【问题描述】:

是否可以不使用直接计算两列的乘积(或例如总和)

grouped.apply(lambda x: (x.a*x.b).sum()

使用起来要快得多(不到我机器上时间的一半)

df['helper'] = df.a*df.b
grouped= df.groupby(something)
grouped['helper'].sum()
df.drop('helper', axis=1)

但我真的不喜欢这样做。 例如,计算每组的加权平均值很有用。这里的 lambda 方法是

grouped.apply(lambda x: (x.a*x.b).sum()/(df.b).sum())

再一次比将助手除以 b.sum() 慢得多。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    我想最终构建一个嵌入式数组表达式评估器(Numexpr on steroids)来做这样的事情。现在我们正在处理 Python 的局限性——如果你实现了一个 Cython 聚合器来执行 (x * y).sum() 那么它可以与 groupby 连接,但理想情况下你可以将 Python 表达式编写为一个函数:

    def weight_sum(x, y):
        return (x * y).sum()
    

    这将获得“JIT 编译”并且与 groupby(...).sum() 一样快。我所描述的是一个非常重要(数月)的项目。如果有一个与 BSD 兼容的 APL 实现,我可能会更快地完成上述操作(只是大声思考)。

    【讨论】:

      【解决方案2】:

      直接对x.a*x.b的结果进行分组怎么样,例如:

      from pandas import *
      from numpy.random import randn
      df = DataFrame({'A' : ['foo', 'bar', 'foo', 'bar',
                     'foo', 'bar', 'foo', 'foo'],
              'B' : ['one', 'one', 'two', 'three',
                     'two', 'two', 'one', 'three'],
              'C' : randn(8), 'D' : randn(8)})
      
      print (df.C*df.D).groupby(df.A).sum()
      

      【讨论】:

      • 这当然有效。但我怀疑首先将整个向量 CD 构建在内存中,然后对其进行分组然后求和。如果我可以有效地遍历行,对 c_id_i 求和(或仅按组构建 C*D,然后在遍历组时求和),我就不必这样做了。
      【解决方案3】:

      多年后通过pydata blaze得到答案

      from blaze import *
      data = Data(df)
      somethings = odo(
      by(data.something, 
         wm = (data.a * data.weights).sum()/data.weights.sum()),
      pd.DataFrame)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-26
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        • 2019-12-30
        • 1970-01-01
        • 2017-08-20
        • 1970-01-01
        相关资源
        最近更新 更多