【问题标题】:Groupby MultiIndex and apply dot product to each group in pandasGroupby MultiIndex 并将点积应用于熊猫中的每个组
【发布时间】:2021-03-01 12:45:19
【问题描述】:

我有数据框 X

>>> X
                    A                              B                    
                   x1        x2 intercept         x1        x2 intercept
Date                                                                    
2020-12-31  48.021395  2.406670         1 -11.538462  2.406670         1
2021-03-31  33.229490  2.410444         1 -23.636364  2.405720         1
2021-06-30  11.498812  2.419787         1 -32.727273  2.402403         1
2021-09-30   5.746014  2.583867         1 -34.000000  2.479682         1
2021-12-31   4.612371  2.739457         1 -39.130435  2.496616         1
2022-03-31   3.679404  2.766474         1 -40.476190  2.411736         1
2022-06-30   3.248155  2.771958         1 -45.945946  2.303280         1

和b系列:

>>> b
         
x1        -0.006
x2         0.083
intercept  0.017

我需要计算每个组 A、B 与 b 的点积,并将结果放入一个数据帧中。我可以明确地遍历每个组,如下所示:

result = pd.concat(
    [X["A"].dot(b).rename("A"), X["B"].dot(b).rename("B"),], axis=1,
)

                   A         B
Date                          
2020-12-31 -0.071375  0.285984
2021-03-31  0.017690  0.358493
2021-06-30  0.148849  0.412763
2021-09-30  0.196985  0.426814
2021-12-31  0.216701  0.459002
2022-03-31  0.224541  0.460031
2022-06-30  0.227584  0.483848

有没有办法在不显式循环组的情况下实现相同的目标?特别是,是否可以先按 MultiIndex 的第一级进行分组,然后将点积应用于每个组?例如:

result=X.groupby(level=[0], axis=1).apply(lambda x: x.dot(b))

这会给我ValueError: matrices are not aligned 错误,我认为这是因为 X 中的组在其列中有两个级别的索引,而 b 的索引是一个简单的索引。所以我需要向 b 添加一个索引级别以匹配 X 中的索引?喜欢:

result=X.groupby(level=[0], axis=1).apply(
    lambda x: x.dot(pd.concat([b], keys=[x.columns.get_level_values(0)[0]]))
)

有了这个我得到ValueError: cannot reindex from a duplicate axis。我卡在这里了。

【问题讨论】:

  • 好问题——输入数据,预期输出,你的代码,超级棒!

标签: pandas pandas-groupby


【解决方案1】:

使用DataFrame.droplevel 删除顶层rename

f = lambda x: x.droplevel(0, axis=1).dot(b).rename(x.name)
result=df.groupby(level=0, axis=1).apply(f)
print (result)
                   A         B
2020-12-31 -0.071375  0.285984
2021-03-31  0.017690  0.358493
2021-06-30  0.148849  0.412763
2021-09-30  0.196985  0.426814
2021-12-31  0.216701  0.459002
2022-03-31  0.224541  0.460031
2022-06-30  0.227584  0.483848

【讨论】:

  • 谢谢!这非常有帮助。正在应用的函数的输入到底是什么?我认为它是顶级索引下的“子数据框”。但是“x.name”表明它是 pandas.Series?
  • @KeCai - 首先是x Dataframe,在x.droplevel(0, axis=1).dot(b) 之后是Series,所以可以在这里使用rename
  • 我天真地认为x.droplevel(0, axis=1).dot(b) 会导致一个无名的Series。如果我这样做df.groupby(level=0, axis=1).get_group("A").droplevel(0, axis=1).dot(b).name 我什么也得不到。我仍然没有得到任何东西。
  • @KeCai - 是的,这是预期的,所以通过分组列添加了rename,这里A, B将无名系列重命名为A, B系列
  • 在阅读了其他一些问题后,似乎只有在调用 apply 时才能看到组的name 属性,例如这里的link。感谢您的耐心回复!
猜你喜欢
  • 2013-06-06
  • 2019-04-28
  • 1970-01-01
  • 2013-02-28
  • 2019-12-19
  • 2019-07-26
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
相关资源
最近更新 更多