我有一个像
这样的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'] } )
答案 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)
您可以使用groupby
和unstack
更好地完成此操作。我还创建了一些额外的列以使事情更清晰。
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