【发布时间】:2017-01-16 15:47:56
【问题描述】:
我有一个包含 4 列(A、B、C、D)的数据框。 D 有一些 NaN 条目。我想用具有相同 A、B、C 值的 D 的平均值填充 NaN 值。
例如,如果 A、B、C、D 的值分别是 x、y、z 和 Nan,那么我希望将 NaN 值替换为 A 值所在行的 D 的平均值, B,C 分别是 x,y,z。
【问题讨论】:
我有一个包含 4 列(A、B、C、D)的数据框。 D 有一些 NaN 条目。我想用具有相同 A、B、C 值的 D 的平均值填充 NaN 值。
例如,如果 A、B、C、D 的值分别是 x、y、z 和 Nan,那么我希望将 NaN 值替换为 A 值所在行的 D 的平均值, B,C 分别是 x,y,z。
【问题讨论】:
df['D'].fillna(df.groupby(['A','B','C'])['D'].transform('mean')) 会比 apply 快
In [2400]: df
Out[2400]:
A B C D
0 1 1 1 1.0
1 1 1 1 NaN
2 1 1 1 3.0
3 3 3 3 5.0
In [2401]: df['D'].fillna(df.groupby(['A','B','C'])['D'].transform('mean'))
Out[2401]:
0 1.0
1 2.0
2 3.0
3 5.0
Name: D, dtype: float64
In [2402]: df['D'] = df['D'].fillna(df.groupby(['A','B','C'])['D'].transform('mean'))
In [2403]: df
Out[2403]:
A B C D
0 1 1 1 1.0
1 1 1 1 2.0
2 1 1 1 3.0
3 3 3 3 5.0
详情
In [2396]: df.shape
Out[2396]: (10000, 4)
In [2398]: %timeit df['D'].fillna(df.groupby(['A','B','C'])['D'].transform('mean'))
100 loops, best of 3: 3.44 ms per loop
In [2397]: %timeit df.groupby(['A','B','C'])['D'].apply(lambda x: x.fillna(x.mean()))
100 loops, best of 3: 5.34 ms per loop
【讨论】:
我认为你需要:
df.D = df.groupby(['A','B','C'])['D'].apply(lambda x: x.fillna(x.mean()))
示例:
df = pd.DataFrame({'A':[1,1,1,3],
'B':[1,1,1,3],
'C':[1,1,1,3],
'D':[1,np.nan,3,5]})
print (df)
A B C D
0 1 1 1 1.0
1 1 1 1 NaN
2 1 1 1 3.0
3 3 3 3 5.0
df.D = df.groupby(['A','B','C'])['D'].apply(lambda x: x.fillna(x.mean()))
print (df)
A B C D
0 1 1 1 1.0
1 1 1 1 2.0
2 1 1 1 3.0
3 3 3 3 5.0
【讨论】:
链接到此问题的副本以获取更多信息: Pandas Dataframe: Replacing NaN with row average
链接中提到的另一种建议方法是在转置上使用简单的 fillna:
df.T.fillna(df.mean(axis=1)).T
【讨论】: