首页 > 解决方案 > Pandas:如何获取一列中每个项目的最后一个每日值并从每行中的值中减去它

问题描述

考虑以下具有时间戳索引的数据帧,该时间戳索引可能具有重复(即非唯一)索引值、指示资产的另一列以及具有该时间戳在该时间戳处的资产值的另一列。

df
                     value asset
2021-03-18 11:00:00      4     A
2021-03-18 11:30:00      1     B
2021-03-18 12:00:00      3     A
2021-03-18 12:30:00      2     A
2021-03-18 13:00:00      3     A
2021-03-18 13:30:00      3     A
2021-03-18 14:00:00      1     A
2021-03-18 14:30:00      2     B

对于每一天,我想获得每项资产的最终价值,并从每行中的价值中减去每项资产的最终价值。所以在上表中,资产 A 的最后日值为 1(时间 2021-03-18 14:00:00),而 B 为 2(时间 2021-03-18 14:30:00)。然后,我想从每行的相应资产价值中扣除这些价值。所以在第一行我想计算new_value等于 4-1 = 3,第二行是 1-2 = -1。

考虑到某些指数值可能会重复,因为它们代表每种资产交易的时间,并且可能同时交易两种资产,我该怎么做。

标签: pythonpandasgroup-bypandas-resample

解决方案


您可以将 agroupby/transform"last"函数一起使用:

df["new_value"] = df["value"] - df.groupby("asset")["value"].transform("last")

print(df)
                     value asset  new_value
2021-03-18 11:00:00      4     A          3
2021-03-18 11:30:00      1     B         -1
2021-03-18 12:00:00      3     A          2
2021-03-18 12:30:00      2     A          1
2021-03-18 13:00:00      3     A          2
2021-03-18 13:30:00      3     A          2
2021-03-18 14:00:00      1     A          0
2021-03-18 14:30:00      2     B          0

groupby/transform操作只是按“资产”对我们的值进行分组,并从每个组中获取“最后一个”元素。然后它将这些值映射回它们的原始组 - 因此该组中的每个元素都成为“最后一个”元素。从那里我们可以在具有相同形状的 2 个数组之间进行简单的减法运算。

s = df.groupby("asset")["value"].transform("last")

print(s)

2021-03-18 11:00:00    1
2021-03-18 11:30:00    2
2021-03-18 12:00:00    1
2021-03-18 12:30:00    1
2021-03-18 13:00:00    1
2021-03-18 13:30:00    1
2021-03-18 14:00:00    1
2021-03-18 14:30:00    2
Name: value, dtype: int64

推荐阅读