问题描述
客户 ID | PROD_ID | 数量 | 价格 | 数量 | 价格 | 数量 | 价格 |
---|---|---|---|---|---|---|---|
31-12-2020 | 31-12-2020 | 01-01-2021 | 01-01-2021 | 02-01-2021 | 02-01-2021 | ||
123 | ABC | 10 | 5 | 10 | 5.4 | 11 | 6 |
123 | efg | 50 | 53 | 50 | 53 | 100 | 53 |
456 | ABC | 10 | 5 | 10 | 5.4 | 10 | 6 |
456 | efg | 10 | 53 | 10 | 53 | 11 | 53 |
列是双索引的,前两行如下所示(日期+价格/数量)。 我想为每个日期(31-12-20 之后)创建一个计算以下内容的新列:
如果数量与前一天不同,则该行的新列包含 0。 ELSE 新列包含(日期数量 * 日期价格)减去(-)(上一个日期数量 * 上一个日期价格)
我创建了一个 for 循环,但它为每个日期迭代数据框,但花费的时间太长。 如何创建这样的功能来应用? PS 索引可靠,但列顺序可能不同。
解决方法
首先,这是您的数据框的干净版本:
df = pd.DataFrame({('123','abc'): [10,5,10,5.4,11,6],('123','efg'): [50,53,50,100,53],('456',5.9,'efg'): [10,53]},index=pd.MultiIndex.from_product([pd.to_datetime(['31-12-2020','01-01-2021','02-01-2021']),['Quantity','Price']]).swaplevel()
).T
数据:
Quantity Price Quantity Price Quantity Price
2020-12-31 2020-12-31 2021-01-01 2021-01-01 2021-02-01 2021-02-01
123 abc 10.0 5.0 10.0 5.4 11.0 6.0
efg 50.0 53.0 50.0 53.0 100.0 53.0
456 abc 10.0 5.9 10.0 5.4 10.0 6.0
efg 10.0 53.0 10.0 53.0 11.0 53.0
然后您可以移动列并计算差异:
(df-df.shift(2,axis=1)).rename(mapper=lambda x: f'{x}_diff',axis='columns',level=0).dropna(axis=1)
输出:
Quantity_diff Price_diff Quantity_diff Price_diff
2021-01-01 2021-01-01 2021-02-01 2021-02-01
123 abc 0.0 0.4 1.0 0.6
efg 0.0 0.0 50.0 0.0
456 abc 0.0 -0.5 0.0 0.6
efg 0.0 0.0 1.0 0.0
组合数据框:
pd.concat([df,(df-df.shift(2,level=0).dropna(axis=1)
],axis=1).sort_index(level=[1,0],ascending=[True,False],axis=1)
输出:
Quantity Price Quantity_diff Quantity Price_diff Price Quantity_diff Quantity Price_diff Price
2020-12-31 2020-12-31 2021-01-01 2021-01-01 2021-01-01 2021-01-01 2021-02-01 2021-02-01 2021-02-01 2021-02-01
123 abc 10.0 5.0 0.0 10.0 0.4 5.4 1.0 11.0 0.6 6.0
efg 50.0 53.0 0.0 50.0 0.0 53.0 50.0 100.0 0.0 53.0
456 abc 10.0 5.9 0.0 10.0 -0.5 5.4 0.0 10.0 0.6 6.0
efg 10.0 53.0 0.0 10.0 0.0 53.0 1.0 11.0 0.0 53.0