Python 比较pandas groupby中的最后一个值
这是我的数据帧:Python 比较pandas groupby中的最后一个值,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,这是我的数据帧: df = pd.DataFrame({'a': list('xxxxxzzz'), 'b':[0,0,1,0,1,0,1,1], 'c': [100, 101, 105, 110, 120, 125, 100, 150], 'd':[0,0,0,1,1,0,0,0]}) 我将他们分组: groups = df.groupby(['a', 'd']) 我想在df中添加另一列,每组显示c的最后一个值与其b为0和b的最后一个值之间的差异(百分比) 例如,在第一组中,我想比较第2行
df = pd.DataFrame({'a': list('xxxxxzzz'), 'b':[0,0,1,0,1,0,1,1], 'c': [100, 101, 105, 110, 120, 125, 100, 150], 'd':[0,0,0,1,1,0,0,0]})
我将他们分组:
groups = df.groupby(['a', 'd'])
我想在df
中添加另一列,每组显示c
的最后一个值与其b
为0和b
的最后一个值之间的差异(百分比)
例如,在第一组中,我想比较第2行和第1行的c
我想要的组
如下所示:
('x', 0)
a b c d result
0 x 0 100 0 3.96
1 x 0 101 0 3.96
2 x 1 105 0 3.96
('x', 1)
a b c d result
3 x 0 110 1 9.09
4 x 1 120 1 9.09
('z', 0)
a b c d result
5 z 0 125 0 20.0
6 z 1 100 0 20.0
7 z 1 150 0 20.0
定义自定义函数并使用 输出
a b c d result
0 x 0 100 0 3.960396
1 x 0 101 0 3.960396
2 x 1 105 0 3.960396
3 x 0 110 1 9.090909
4 x 1 120 1 9.090909
5 z 0 125 0 20.000000
6 z 1 100 0 20.000000
7 z 1 150 0 20.000000
如果您单独需要每个组,只需使用列表理解
[func(g)for n,g in df.groupby(['a','d'])]
我们可以在这里执行以下操作:
.pct\u change
方法计算每行的百分比变化result
列的值填入NaN
b填充a
或ffill
a b c d result
0 x 0 100 0 NaN
1 x 0 101 0 NaN
2 x 1 105 0 3.96
3 x 0 110 1 NaN
4 x 1 120 1 9.09
5 z 0 125 0 NaN
6 z 1 100 0 20.00
7 z 1 150 0 NaN
# first we apply .pct_change to all rows
df['result'] = abs(round(df.groupby(['a', 'd', 'b']).c.pct_change() * 100, 2))
# after that we check if the value if b = 1 and the value of the row before = 0 and we fill in NaN if condition not true
df['result'] = np.where((df.b == 1) & (df.b.shift(1) == 0), df.result, np.NaN)
a b c d result
0 x 0 100 0 NaN
1 x 0 101 0 NaN
2 x 1 105 0 3.96
3 x 0 110 1 NaN
4 x 1 120 1 9.09
5 z 0 125 0 NaN
6 z 1 100 0 20.00
7 z 1 150 0 NaN
# then backfill and forwardfill NaN
df.result.fillna(method='bfill', inplace=True)
df.result.fillna(method='ffill', inplace=True)
print(df)
a b c d result
0 x 0 100 0 3.96
1 x 0 101 0 3.96
2 x 1 105 0 3.96
3 x 0 110 1 9.09
4 x 1 120 1 9.09
5 z 0 125 0 20.00
6 z 1 100 0 20.00
7 z 1 150 0 20.00