有条件地聚合Pandas DataFrame

时间:2016-07-19 01:17:22

标签: python pandas dataframe

我有一个看起来像这样的DataFrame:

import pandas as pd

df = pd.DataFrame([[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0],
                   [9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0],
                   [17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0]], 
                   columns=['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'])

      A     B     C     D     E     F     G     H
0   1.0   2.0   3.0   4.0   5.0   6.0   7.0   8.0
1   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0
2  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0

我有一个列列表:

l = ['A', 'C', 'D', 'E']

对于列表中的每个元素,我想获得它前面的dataframe列的平均值加上它自己列中值的两倍。因此,A仅依赖于自身,C将取决于A及其本身,D将取决于AC的总和}和它自身以及E将取决于ACD及其本身。我已通过以下方式完成了我的需求:

for i, col in enumerate(l):
    other_cols = l[:i]
    df['tmp_' + col] = df[other_cols].mean(axis=1) + 2.0 * df[col]

      A     B     C     D     E     F     G     H  tmp_A  tmp_C  tmp_D  \
0   1.0   2.0   3.0   4.0   5.0   6.0   7.0   8.0    NaN    7.0   10.0   
1   9.0  10.0  11.0  12.0  13.0  14.0  15.0  16.0    NaN   31.0   34.0   
2  17.0  18.0  19.0  20.0  21.0  22.0  23.0  24.0    NaN   55.0   58.0   

       tmp_E  
0  12.666667  
1  36.666667  
2  60.666667  

我想知道是否有更多的Pythonic方法来完成相同的事情,而不是必须通过for循环?

1 个答案:

答案 0 :(得分:1)

IIUC,你可以在现代熊猫中使用expanding来处理这个问题:

>>> cols = ["A","C","D","E"]
>>> df[cols] * 2 + df[cols].expanding(axis=1).mean().shift(axis=1).fillna(0)

      A     C     D          E
0   2.0   7.0  10.0  12.666667
1  18.0  31.0  34.0  36.666667
2  34.0  55.0  58.0  60.666667

这会再现您预期的新列(并且A的值变为其原始值的两倍,这要归功于fillna将NaNs转换为0)。

我们可以看到这是一步一步来的:

开始
>>> df[cols]

      A     C     D     E
0   1.0   3.0   4.0   5.0
1   9.0  11.0  12.0  13.0
2  17.0  19.0  20.0  21.0

>>> df[cols].expanding(axis=1)
Expanding [min_periods=1,center=False,axis=1]

我们可以先sum,因为它更容易直观检查:

>>> df[cols].expanding(axis=1).sum()

      A     C     D     E
0   1.0   4.0   8.0  12.0
1   9.0  20.0  32.0  36.0
2  17.0  36.0  56.0  60.0

>>> df[cols].expanding(axis=1).mean()

      A     C          D     E
0   1.0   2.0   2.666667   4.0
1   9.0  10.0  10.666667  12.0
2  17.0  18.0  18.666667  20.0

>>> df[cols].expanding(axis=1).mean().shift(axis=1)

    A     C     D          E
0 NaN   1.0   2.0   2.666667
1 NaN   9.0  10.0  10.666667
2 NaN  17.0  18.0  18.666667

>>> df[cols].expanding(axis=1).mean().shift(axis=1).fillna(0)

     A     C     D          E
0  0.0   1.0   2.0   2.666667
1  0.0   9.0  10.0  10.666667
2  0.0  17.0  18.0  18.666667