问题描述
我正在尝试自学 python,所以这个问题比具体问题更笼统,但我真的很感激一些指点!我想知道如何遍历数据帧,对每一行执行计算,在其中将列值之一添加到具有相同特征的前一行中的值。举例来说,假设我有以下 df:
date order_id price cust_id
0 2020-05-01 101 10.5 A1
1 2020-06-03 102 116.3 A2
2 2020-06-04 103 58.4 A3
3 2020-06-05 104 62.5 A1
4 2020-06-06 105 40.2 A1
5 2020-11-10 106 15.6 A4
6 2020-11-15 107 89.4 A5
7 2020-11-20 108 72.1 A6
8 2020-11-21 109 53.6 A5
9 2020-11-22 110 14.5 A4
我想创建一个新列“rtotal”,它给出了迄今为止特定客户订单价值的运行总和。我一直在尝试各种不同的方法,但一无所获。我一直在尝试这些方法:
df=df.assign(rtotal="")
for i in range (0,len(df)):
df.rtotal[i] = df['price'].iloc[i] + df.loc[df['cust_id'].shift(-1)== df.cust_id[i],'rtotal']
我遇到的两个问题首先是如何处理出现新 cust_id 的行(即这是它们的第一个顺序,因此不存在以前的值)以及如何让循环查看具有相同 cust_id 的最后一个值,取总和,然后加上当前订单的价格。
正如我所说,我正在努力学习如何解决这样的一般问题,而不仅仅是这个特定问题,因此非常感谢您收到任何指示!
解决方法
让我们试试groupby cumsum:
import pandas as pd
df = pd.DataFrame({'date': {0: '2020-05-01',1: '2020-06-03',2: '2020-06-04',3: '2020-06-05',4: '2020-06-06',5: '2020-11-10',6: '2020-11-15',7: '2020-11-20',8: '2020-11-21',9: '2020-11-22'},'order_id': {0: 101,1: 102,2: 103,3: 104,4: 105,5: 106,6: 107,7: 108,8: 109,9: 110},'price': {0: 10.5,1: 116.3,2: 58.4,3: 62.5,4: 40.2,5: 15.6,6: 89.4,7: 72.1,8: 53.6,9: 14.5},'cust_id': {0: 'A1',1: 'A2',2: 'A3',3: 'A1',4: 'A1',5: 'A4',6: 'A5',7: 'A6',8: 'A5',9: 'A4'}})
df['rtotal'] = df.groupby('cust_id')['price'].cumsum()
print(df)
输出:
date order_id price cust_id rtotal 0 2020-05-01 101 10.5 A1 10.5 1 2020-06-03 102 116.3 A2 116.3 2 2020-06-04 103 58.4 A3 58.4 3 2020-06-05 104 62.5 A1 73.0 4 2020-06-06 105 40.2 A1 113.2 5 2020-11-10 106 15.6 A4 15.6 6 2020-11-15 107 89.4 A5 89.4 7 2020-11-20 108 72.1 A6 72.1 8 2020-11-21 109 53.6 A5 143.0 9 2020-11-22 110 14.5 A4 30.1
(按 cust_id
排序以便更容易查看)
df = df.sort_values('cust_id')
date order_id price cust_id rtotal 0 2020-05-01 101 10.5 A1 10.5 3 2020-06-05 104 62.5 A1 73.0 4 2020-06-06 105 40.2 A1 113.2 1 2020-06-03 102 116.3 A2 116.3 2 2020-06-04 103 58.4 A3 58.4 5 2020-11-10 106 15.6 A4 15.6 9 2020-11-22 110 14.5 A4 30.1 6 2020-11-15 107 89.4 A5 89.4 8 2020-11-21 109 53.6 A5 143.0 7 2020-11-20 108 72.1 A6 72.1