Python - 使用pandas pivot_table对特定值求和

时间:2018-03-07 14:57:18

标签: python pandas

我有一个像

这样的pandas数据框
ACCOUNT AMOUNT STATUS 
1         -2      1
2         2       0
2         -1      0
1         2       1 
1         2       1

这是想转换成像

这样的数据框
ACCOUNT  STATUS COUNT>0 COUNT<0 AMOUNT>0 AMOUNT<0 
1          1      2        1        4         2
2          0      1        1        2         1

如果AMOUNT是&gt;那么基本上分开或者&lt;比0然后计算并对结果求和。我目前有以下内容,但无法获得拆分AMOUNT权限。

Data = pd.pivot_table(trans, values =['Status', 'AMOUNT'], index = ['ACCOUNT'], aggfunc = {'Status':np.mean, 'AMOUNT': [np.sum, 'count'] } )

3 个答案:

答案 0 :(得分:3)

使用np.sign
此函数返回-1 / 0 / 1的数组,具体取决于值的符号。基本上给我一个方便的方法来识别更少,相等或大于零的东西。我在group by语句中使用它,并使用agg计算值的数量,并使用sum来产生总数。在通过3个向量分组之后,我最终得到3层多索引。我取消堆叠以获取最后一层并将其旋转以包含在列中。最后一层是sign层。

df.groupby(
    ['ACCOUNT', 'STATUS', np.sign(df.AMOUNT)]
).AMOUNT.agg(['count', 'sum']).unstack()

               count    sum   
AMOUNT            -1  1  -1  1
ACCOUNT STATUS                
1       1          1  2  -2  4
2       0          1  1  -1  2

模仿OP的预期输出的额外努力:
在这里,我做同样的事情。但是我添加了几个重命名列,组合图层和取绝对值的步骤。

df.groupby(
    ['ACCOUNT', 'STATUS', np.sign(df.AMOUNT).map({-1: '<0', 0: '=0', 1: '>0'})]
).AMOUNT.agg(['count', 'sum']).rename(
    columns=dict(count='COUNT', sum='AMOUNT')
).unstack().abs().pipe(
    lambda d: d.set_axis(d.columns.map('{0[0]}{0[1]}'.format), 1, inplace=False)
)

                COUNT<0  COUNT>0  AMOUNT<0  AMOUNT>0
ACCOUNT STATUS                                      
1       1             1        2         2         4
2       0             1        1         1         2

答案 1 :(得分:1)

这是尝试修复您的pivot_table

pd.pivot_table(df.assign(new=df.AMOUNT.gt(0)), values =['AMOUNT'], index = ['ACCOUNT','STATUS'],columns='new',aggfunc = { 'AMOUNT': [np.sum, 'count'] } ).abs()
Out[431]: 
               AMOUNT                  
                count         sum      
new             False True  False True 
ACCOUNT STATUS                         
1       1           1     2     2     4
2       0           1     1     1     2

答案 2 :(得分:0)

您可以使用groupbyunstack更好地完成此操作。我还创建了一些额外的列以使事情更清晰。

data = pd.DataFrame(
    [[1, -2, 1],
     [2, 2, 0],
     [2, -1, 0],
     [1,  2, 1],
     [1,  2, 1] 
    ],
    columns = ['ACCOUNT', 'AMOUNT', 'STATUS']
)

data['AMOUNT_POSITIVE'] = data['AMOUNT'] > 0
data['AMOUNT_ABSOLUTE'] = data['AMOUNT'].abs()

result = (data
          .groupby(["ACCOUNT", "STATUS", "AMOUNT_POSITIVE"])['AMOUNT_ABSOLUTE']
          .agg(['count', 'sum'])
          .unstack("AMOUNT_POSITIVE")
         )

print(result)

你得到了你的桌子:

                count         sum      
AMOUNT_POSITIVE False True  False True 
ACCOUNT STATUS                         
1       1           1     2     2     4
2       0           1     1     1     2