假设我有以下熊猫数据框:
>>> import pandas as pd
>>> df = pd.DataFrame([1,2,4, None, None, None, None, -1, 1, None, None])
>>> df
0
0 1.0
1 3.0
2 4.0
3 NaN
4 NaN
5 NaN
6 NaN
7 -1.0
8 1.0
9 NaN
10 NaN
我想用从前一个值开始的指数衰减来填充缺失的值,给出:
>>> df_result
0
0 1.0
1 2.0
2 4.0
3 4.0 # NaN replaced with previous value
4 2.0 # NaN replaced previous value / 2
5 1.0 # NaN replaced previous value / 2
6 0.5 # NaN replaced previous value / 2
7 -1.0
8 1.0
9 1.0 # NaN replaced previous value
10 0.5 # NaN replaced previous value / 2
有了fillna
,我有method='pad'
,但我的公式无法满足要求。
对于interpolate
,我不确定是否可以给出特定的指数衰减公式,并且仅考虑最后一个非NaN值。
我正在考虑创建一个单独的数据帧df_replacements
,而不是在其他地方用0.5
初始化为NaN和0
,做一个cumprod(以某种方式,我需要将运行产品重置为1每第一个NaN),然后依次为df_result = df.fillna(df_replacements, inplace=True)
有没有简单的方法可以用熊猫取代这种动物?
答案 0 :(得分:3)
在您的情况下,将nan向前填充,然后我们groupby
找到连续的NaN
,得到cumcount
s=df[0].ffill()
df[0].fillna(s[df[0].isnull()].mul((1/2)**(df[0].groupby(df[0].notnull().cumsum()).cumcount()-1),0))
Out[655]:
0 1.0
1 2.0
2 4.0
3 4.0
4 2.0
5 1.0
6 0.5
7 -1.0
8 1.0
9 1.0
10 0.5
Name: 0, dtype: float64
由OP编辑:具有更明确的变量名称的相同解决方案:
ffilled = df[0].ffill()
is_na = df[0].isnull()
group_ids = df[0].notnull().cumsum()
mul_factors = (1 / 2) ** (df[0].groupby(group_ids).cumcount() - 1)
result = df[0].fillna(ffilled[is_na].mul(mul_factors, 0))