Python pandas:我们可以避免在 groupby/apply 这种情况下应用吗?

Posted

技术标签:

【中文标题】Python pandas:我们可以避免在 groupby/apply 这种情况下应用吗?【英文标题】:Python pandas: can we avoid apply in this case of groupby/apply? 【发布时间】:2019-08-24 08:27:41 【问题描述】:

我听说过很多关于 pandas apply 很慢,应该尽量少用。

我这里有个情况:

df = pd.DataFrame('Date': ['2019-01-02', '2019-01-03', '2019-01-04'],
          'Fund_ID': [9072, 9072, 9072],
          'Fund_Series': ['A', 'A', 'A'],
          'Value': [1020.0, 1040.4, 1009.188],
          'Dividend': [0.0, 0.0, 52.02])

我想在分组后做一些调整权重操作,如下所示:

df['Pct_Change_Adjusted'] = df.groupby(['Fund_ID', 'Fund_Series'], as_index=False) \
                              .apply(lambda x: (x.Value + x.Dividend)/(x.Value.shift()+x.Dividend.shift())  ) \
                              .reset_index(drop=True).values[0]

print(df)

         Date  Dividend  Fund_ID Fund_Series     Value  Pct_Change_Adjusted
0  2019-01-02      0.00     9072           A  1020.000                  NaN
1  2019-01-03      0.00     9072           A  1040.400                 0.02
2  2019-01-04     52.02     9072           A  1009.188                 0.02

这里有没有其他 apply 的替代品可以提高效率或至少是第二种做事方式!!

注意:我不是在谈论 dask 和其他并行化,只是纯粹的 pandas。

必填: 不使用 apply 计算列 Pct_Change_Adjusted

【问题讨论】:

应该是(x.Value + x.Dividend)/(x.Value.shift()+x.Dividend.shift()) @Wen-Ben 是的,更新了问题。 【参考方案1】:

是的,这是 100% 可使用 groupby.pct_change 向量化的:

(df.Value + df.Dividend).groupby([df.Fund_ID, df.Fund_Series]).pct_change()

0     NaN
1    0.02
2    0.02
dtype: float64

df['Pct_Change_Adjusted'] = (df.assign(Foo=df['Value'] + df['Dividend'])
                               .groupby(['Fund_ID', 'Fund_Series'])
                               .Foo
                               .pct_change())

df

         Date  Fund_ID Fund_Series     Value  Dividend  Pct_Change_Adjusted
0  2019-01-02     9072           A  1020.000      0.00                  NaN
1  2019-01-03     9072           A  1040.400      0.00                 0.02
2  2019-01-04     9072           A  1009.188     52.02                 0.02

【讨论】:

你使用.groupby([df['Fund_ID'], df['Fund_Series']])而不是.groupby(['Fund_ID', 'Fund_Series'])有什么原因吗? @Erfan 是的。 (df.Value + df.Dividend) 返回一个系列。除非我将系列分配回df,否则我无法将字符串传递给 groupby,我必须直接传递列/系列。为清晰起见进行了编辑。 在前一种情况下,我调用了 Series.GroupBy。现在,编辑后,我调用 DataFrame.GroupBy。

以上是关于Python pandas:我们可以避免在 groupby/apply 这种情况下应用吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Pandas Python 中合并时避免笛卡尔坐标

Python pandas groupby sum显示错误的输出

Python pandas 使用 fillna() 来避免对 NaN 值进行错误拆分

pandas读取csv文件时避免科学计数法(xxxe+09)

11、pandas的修改列名和索引rename()

Python,使用pandas保存数据为csv格式的文件