通过在另一列上应用条件来填充 na

Fill na by applying condition on another column

有一个包含两列的 df。第一列有月度值,但第二列只包含季度值。我想用第一列的相同百分比变化来填充第二列的 NA 值。比如原来的df是这样的:

            ColA   ColB 
2019-12-31   100    5
2020-01-31   200    NA
2020-02-28   300    NA
2020-03-31   200    20
2020-04-30   300    NA

我想计算colA的百分比变化,然后根据百分比变化填充colB。结果应如下所示:

            ColA   ColB 
2019-12-31   100    5
2020-01-31   200    10
2020-02-28   300    15
2020-03-31   200    20
2020-04-30   300    30

我可以通过 pct_change() 计算 colA 的百分比变化,但不知道如何仅应用于 colB 的 na 值。请问有什么解决办法吗?

第一个想法是创建 percenta change 列并按 ColB - 第一个值反向百分比变化。

df['pct'] = df['ColA'].pct_change()

df['ColB'] = df['pct'].add(1,fill_value=0).cumprod().mul(df.loc[df.index[0], 'ColB'])
print (df)
            ColA  ColB       pct
2019-12-31   100   5.0       NaN
2020-01-31   200  10.0  1.000000
2020-02-28   300  15.0  0.500000
2020-03-31   200  10.0 -0.333333
2020-04-30   300  15.0  0.500000

如果可能,创建组并获取每个组的百分比,在 ColB 中定义非缺失值使用:

df['g'] = df['ColB'].notna().cumsum()
df['pct'] = df.groupby('g')['ColA'].pct_change()

df['ColB'] = df.groupby('g')['pct'].transform(lambda x: x.add(1,fill_value=0).cumprod().mul(df.loc[x.index[0], 'ColB']))
print (df)
            ColA  ColB  g  pct
2019-12-31   100   5.0  1  NaN
2020-01-31   200  10.0  1  1.0
2020-02-28   300  15.0  1  0.5
2020-03-31   200  20.0  2  NaN
2020-04-30   300  30.0  2  0.5

您可以简单地计算一个比率,填充它,然后使用 combine_first 更新缺失值:

ratio = (df['ColB'] / df['ColA']).ffill()
df['ColB'] = df['ColB'].combine_first(df['ColA'] * ratio)

得到预期的结果就够了:

            ColA  ColB
2019-12-31   100   5.0
2020-01-31   200  10.0
2020-02-28   300  15.0
2020-03-31   200  20.0
2020-04-30   300  30.0