Pandas:用前一个和下一个非缺失值的平均值动态替换 NaN 值
Posted
技术标签:
【中文标题】Pandas:用前一个和下一个非缺失值的平均值动态替换 NaN 值【英文标题】:Pandas: Dynamically replace NaN values with the average of previous and next non-missing values 【发布时间】:2019-01-04 16:06:46 【问题描述】:我有一个带有 NaN
值的数据框 df
,我想用上一个和下一个非缺失值的平均值动态替换它们。
In [27]: df
Out[27]:
A B C
0 -0.166919 0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 NaN -2.027325 1.533582
4 NaN NaN 0.461821
5 -0.788073 NaN NaN
6 -0.916080 -0.612343 NaN
7 -0.887858 1.033826 NaN
8 1.948430 1.025011 -2.982224
9 0.019698 -0.795876 -0.046431
例如,A[3]
是 NaN
,所以它的值应该是 (-0.120211-0.788073)/2 = -0.454142。 A[4]
那么应该是 (-0.454142-0.788073)/2 = -0.621108。
因此,结果数据框应如下所示:
In [27]: df
Out[27]:
A B C
0 -0.166919 0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 -0.454142 -2.027325 1.533582
4 -0.621108 -1.319834 0.461821
5 -0.788073 -0.966089 -1.260202
6 -0.916080 -0.612343 -2.121213
7 -0.887858 1.033826 -2.551718
8 1.948430 1.025011 -2.982224
9 0.019698 -0.795876 -0.046431
这是处理缺失值的好方法吗?我不能简单地replace them by the average values of each column,因为我的数据是时间序列的,并且会随着时间的推移而增加。 (初始值可能是 0 美元,最终值可能是 100000 美元,所以平均值是 50000 美元,这可能比 NaN 值大/小得多)。
【问题讨论】:
您是否真的依附于您为填写NaN
提供的公式,或者您只是想在前后有一个接近另一个值的值。试试df.interpolate()
,它会在NaN
中填充您要查找的值,但不会使用您使用公式计算的确切值
【参考方案1】:
您可以尝试了解几何级数平均值背后的逻辑
s=df.isnull().cumsum()
t1=df[(s==1).shift(-1).fillna(False)].stack().reset_index(level=0,drop=True)
t2=df.lookup(s.idxmax()+1,s.idxmax().index)
df.fillna(t1/(2**s)+t2*(1-0.5**s)*2/2)
Out[212]:
A B C
0 -0.166919 0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 -0.454142 -2.027325 1.533582
4 -0.621107 -1.319834 0.461821
5 -0.788073 -0.966089 -1.260201
6 -0.916080 -0.612343 -2.121213
7 -0.887858 1.033826 -2.551718
8 1.948430 1.025011 -2.982224
9 0.019698 -0.795876 -0.046431
解释:
第一个 NaN x/2+y/2=1st
2nd NaN 1st/2+y/2=2nd
3rd NaN 2nd/2+y/2+3rd
然后x/(2**n)+y(1-(1/2)**n)/(1-1/2),这就是关键
【讨论】:
如果您在同一列中有另一组NaN
,这会起作用吗?例如,如果 A 列中的第 7 行和第 8 行也是NaN
?我知道这不是问题,只是想知道:)
进展顺利。 +1【参考方案2】:
遇到了一个类似的问题。 以下代码对我有用。
def fill_nan_with_mean_from_prev_and_next(df):
NANrows = pd.isnull(df).any(1).nonzero()[0]
null_df = df.isnull()
for row in NANrows :
for colum in range(0,df.shape[1]):
if(null_df.iloc[row][colum]):
df.iloc[row][colum] = (df.iloc[row-1][colum]+df.iloc[row-1][colum])/2
return df
也许它也对某人有帮助。
【讨论】:
以上是关于Pandas:用前一个和下一个非缺失值的平均值动态替换 NaN 值的主要内容,如果未能解决你的问题,请参考以下文章
pandas使用dropna函数删除dataframe中列非缺失值的个数小于某一比例阈值的数据列