多级索引DataFrame运算:新增PL列计算持仓差值
为分组DataFrame新增PL列的实现方案
需求
给现有DataFrame新增PL列,规则如下:
- 按
Client、Product、Buy Date进行分组 - 每组内,当日
Position与前一日Position的差值即为当日PL值 - 每组首次出现的
Position Date对应的PL设为0
原始数据构造
import pandas as pd data = {'Client': ['Client 1', 'Client 1', 'Client 2', 'Client 2', 'Client 1', 'Client 1', 'Client 2', 'Client 2'], 'Position Date': ['2022-01-02', '2022-01-02', '2022-01-02', '2022-01-02', '2022-01-03', '2022-01-03', '2022-01-03', '2022-01-03'], 'Product': ['Product 1', 'Product 4', 'Product 2', 'Product 3', 'Product 1', 'Product 4', 'Product 2', 'Product 3'], 'Buy Date': ['2022-05-02', '2022-06-02', '2022-03-12', '2022-01-25', '2022-05-02', '2022-06-02', '2022-03-12', '2022-01-25'], 'Position': [100, 5000, 120, 50, 150, 7000, 200, 100]} df = pd.DataFrame(data).set_index(['Position Date', 'Client', 'Product', 'Buy Date'])
解决代码
# 重置索引,方便分组和日期处理 df_reset = df.reset_index() # 分组计算Position差值,首次行填充0 df_reset['PL'] = df_reset.groupby(['Client', 'Product', 'Buy Date'])['Position'].diff().fillna(0) # 恢复原复合索引 df = df_reset.set_index(['Position Date', 'Client', 'Product', 'Buy Date'])
结果展示
处理后的数据表如下:
| Position Date | Client | Product | Buy Date | Position | PL |
|---|---|---|---|---|---|
| 2022-01-02 | Client 1 | Product 1 | 2022-05-02 | 100 | 0.0 |
| 2022-01-02 | Client 1 | Product 4 | 2022-06-02 | 5000 | 0.0 |
| 2022-01-02 | Client 2 | Product 2 | 2022-03-12 | 120 | 0.0 |
| 2022-01-02 | Client 2 | Product 3 | 2022-01-25 | 50 | 0.0 |
| 2022-01-03 | Client 1 | Product 1 | 2022-05-02 | 150 | 50.0 |
| 2022-01-03 | Client 1 | Product 4 | 2022-06-02 | 7000 | 2000.0 |
| 2022-01-03 | Client 2 | Product 2 | 2022-03-12 | 200 | 80.0 |
| 2022-01-03 | Client 2 | Product 3 | 2022-01-25 | 100 | 50.0 |
代码说明
- 重置索引:把复合索引转为普通列,避免索引对分组计算的干扰
- 分组diff计算:
groupby指定分组字段后,diff()自动计算每组内当前行与上一行的Position差值,第一行无前置数据会返回NaN - 填充0值:用
fillna(0)将每组第一行的NaN替换为0,满足首次日期PL为0的要求 - 恢复索引:还原为原有的复合索引结构,保持数据格式一致
内容的提问来源于stack exchange,提问作者João Weckerle
相关产品推荐
相关产品推荐

