Pandas Dataframe:用行平均值替换NaN

问题描述 投票:13回答:2

我正在努力学习大熊猫,但我对以下内容感到困惑。我想替换NaNs是一个具有行平均值的数据帧。因此像df.fillna(df.mean(axis=1))这样的东西应该可以工作,但由于某种原因它不适合我。我错过了什么,我做错了什么?是因为它没有实施;见link here

import pandas as pd
import numpy as np
​
pd.__version__
Out[44]:
'0.15.2'

In [45]:
df = pd.DataFrame()
df['c1'] = [1, 2, 3]
df['c2'] = [4, 5, 6]
df['c3'] = [7, np.nan, 9]
df

Out[45]:
    c1  c2  c3
0   1   4   7
1   2   5   NaN
2   3   6   9

In [46]:  
df.fillna(df.mean(axis=1)) 

Out[46]:
    c1  c2  c3
0   1   4   7
1   2   5   NaN
2   3   6   9

但是这样的事情看起来很好

df.fillna(df.mean(axis=0)) 

Out[47]:
    c1  c2  c3
0   1   4   7
1   2   5   8
2   3   6   9
python pandas dataframe missing-data
2个回答
23
投票

如注释,fillna的轴参数是NotImplemented

df.fillna(df.mean(axis=1), axis=1)

注意:这在此非常关键,因为您不希望用第n行平均值填充第n列。

现在你需要迭代:

In [11]: m = df.mean(axis=1)
         for i, col in enumerate(df):
             # using i allows for duplicate columns
             # inplace *may* not always work here, so IMO the next line is preferred
             # df.iloc[:, i].fillna(m, inplace=True)
             df.iloc[:, i] = df.iloc[:, i].fillna(m)

In [12]: df
Out[12]:
   c1  c2   c3
0   1   4  7.0
1   2   5  3.5
2   3   6  9.0

另一种方法是填充转置然后转置,这可能更有效...

df.T.fillna(df.mean(axis=1)).T

11
投票

作为替代方案,你也可以使用带有apply表达式的lambda,如下所示:

df.apply(lambda row: row.fillna(row.mean()), axis=1)

屈服也

    c1   c2   c3
0  1.0  4.0  7.0
1  2.0  5.0  3.5
2  3.0  6.0  9.0
© www.soinside.com 2019 - 2024. All rights reserved.