首页 > 解决方案 > 熊猫:以固定间隔计算差异,并在没有更多记录时更改为可变间隔以使用最早的记录

问题描述

我得到了一个带有每月记录的 DataFrame,我想计算最近一个月与 6 个月前的差异。但是,对于那些没有完成 6 个月记录的人,我可以像下面这样计算与最早记录的人的差异吗?

Client       Month   CAV 
 A          2021-09   30  
 A          2021-08   20
 A          2021-07   10
 A          2021-06    5
 A          2021-05   10
 A          2021-04    5
 A          2021-03   10
 B          2021-08   50
 B          2021-07   10
 B          2021-06   30     

我用过df['CAV_diff'] = df.groupby('Client')['CAV'].diff(-5),它会得到:

 Client        Month   CAV     CAV_diff  
   A          2021-09   30        25 (=30-5) 
   A          2021-08   20        10 (=20-10)
   A          2021-07   10        N/A
   A          2021-06    5        N/A
   A          2021-05   10        N/A
   A          2021-04    5        N/A
   A          2021-03   10        N/A
   B          2021-08   50        N/A
   B          2021-07   10        N/A
   B          2021-06   30        N/A

我可以得到如下结果:

 Client        Month   CAV     CAV_diff  
   A          2021-09   30        25 (=30-5)  
   A          2021-08   20        10 (=20-10)
   A          2021-07   10        0  (=10-10)
   A          2021-06    5        -5 (=5-10)
   A          2021-05   10        0
   A          2021-04    5        -5
   A          2021-03   10        0
   B          2021-08   50        20
   B          2021-07   10        -20
   B          2021-06   30        0

标签: pythonpandasdiff

解决方案


您可以在.groupby()++上使用shift()fillna()transform()'last'

在这里,当没有 的值时,我们通过使用+ on来获取.shift()组中的最后一个条目来获取 的值。.groupby()transform()'last'.fillna()

 df['CAV_diff'] = df['CAV'] - df.groupby('Client')['CAV'].shift(-5).fillna(df.groupby('Client')['CAV'].transform('last'))

结果:

print(df)

  Client    Month  CAV  CAV_diff
0      A  2021-09   30      25.0
1      A  2021-08   20      10.0
2      A  2021-07   10       0.0
3      A  2021-06    5      -5.0
4      A  2021-05   10       0.0
5      A  2021-04    5      -5.0
6      A  2021-03   10       0.0
7      B  2021-08   50      20.0
8      B  2021-07   10     -20.0
9      B  2021-06   30       0.0

解释:

让我们比较一下shift(-5)有和没有这.fillna()部分的值:

df.groupby('Client')['CAV'].shift(-5)

0     5.0
1    10.0
2     NaN
3     NaN
4     NaN
5     NaN
6     NaN
7     NaN
8     NaN
9     NaN
Name: CAV, dtype: float64

由于客户端 A 和客户端 B 分别只有 7 行和 3 行条目,因此只有客户端 A 的前 2 个条目shift(-5)有值。客户 B 没有价值。

使用fillna()Client 组的最后一个条目,我们得到:

 df.groupby('Client')['CAV'].shift(-5).fillna(df.groupby('Client')['CAV'].transform('last'))


0     5.0
1    10.0
2    10.0
3    10.0
4    10.0
5    10.0
6    10.0
7    30.0
8    30.0
9    30.0
Name: CAV, dtype: float64

条目用NaN每组中的最后一个值填充。


推荐阅读