Pandas:先查询groupby和sum,最后填充na

xmjla07d  于 2022-12-16  发布在  其他
关注(0)|答案(1)|浏览(103)

我试图做一些看起来完全不可读的事情,我想知道我是否可以让它更简单(我打赌我可以,但找不到方法)。
这是我的代码:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(5,3), columns=list('ABC'))
df['D'] = [1,2,2,1,2]

df1 = df.query('B<1')[['A', 'D']].groupby('D').sum().reset_index()

df = df.set_index(['D'])
df1 = df1.set_index(['D'])

df2 = df1.join(df[['B', 'C']], how='inner', on=['D']).reset_index()

df2.loc[df2['B'] > 1, 'A'] = 0

df

          A         B         C
D
1  0.702204  2.288548 -0.251334
2 -0.346842 -1.486899 -0.576246
2 -1.183607 -2.210152  0.409037
1 -0.884401  0.124899  1.719387
2  0.305400  0.988187  0.160168

df2
   D         A         B         C
0  1  0.000000  2.288548 -0.251334
1  1 -0.884401  0.124899  1.719387
2  2 -1.225049 -1.486899 -0.576246
3  2 -1.225049 -2.210152  0.409037
4  2 -1.225049  0.988187  0.160168

这是我得出的结论,它是正确的,但不是真正可读的。
我需要:
1.查询B〈1的每一行
1.按另一列分组(D)
1.第三列求和(A)
1.在1中不匹配查询的每一行中放入0
没有那些丑陋的代码有可能做到这一点吗?
谢谢你,

ctehm74n

ctehm74n1#

如果需要与df2相同的顺序,则首先按D对值进行排序,然后如果1更大,则将A转换为0,因此可以将GroupBy.transformsum用于大小与原始DataFrame相同的新系列,如果B更大,则最后设置0,如1,并分配给列A

#query 4 use query 1, so possible reuse mask
m = df.B.lt(1)

df['A'] = df['A'].where(m, 0).groupby(df['D']).transform('sum').where(m,0)
print (df)
   D         A         B         C
0  1  0.000000  2.288548 -0.251334
1  2 -1.225049 -1.486899 -0.576246
2  2 -1.225049 -2.210152  0.409037
3  1 -0.884401  0.124899  1.719387
4  2 -1.225049  0.988187  0.160168

工作原理:

print (df['A'].where(m, 0))
0    0.000000
1   -1.225049
2   -1.225049
3   -0.884401
4   -1.225049
Name: A, dtype: float64

print (df['A'].where(m, 0).groupby(df['D']).transform('sum'))
0   -0.884401
1   -3.675147
2   -3.675147
3   -0.884401
4   -3.675147
Name: A, dtype: float64

print (df['A'].where(m, 0).groupby(df['D'])
              .transform('sum').where(m,0))
0    0.000000
1   -3.675147
2   -3.675147
3   -0.884401
4   -3.675147
Name: A, dtype: float64

相关问题