这很难表达。但是,让我向您展示我正在努力实现的目标。

df

Y  X
a  10
a  5
a  NaN
b  12
b  13
b  NaN
c  5
c  NaN
c  5
c  6


Y: 10 non-null object
X: 7 non-null int64


从Y列中获取类别“ a”,它具有X值的中位数(10 + 5/2),“ a”的另一个缺失值必须用该中值填充。

同样,对于Y列中的类别“ b”,在X列中的所有不丢失值中,X的中值为(12 + 13/2)

对于Y列中的类别“ c”,在X列中的所有不缺失值中,X的中值为5(中间值)

我使用了很长的重复代码,如下所示。

    grouped = df.groupby(['Y'])[['X']]
    grouped.agg([np.median])

                X
                median
    Y
    a           7.5
    b           12.5
    c           5

    df.X = df.X.fillna(-1)

    df.loc[(df['Y'] == 'a') & (df['X'] == -1), 'X'] = 7.5
    df.loc[(df['Y'] == 'b') & (df['X'] == -1), 'X'] = 12.5
    df.loc[(df['Y'] == 'c') & (df['X'] == -1), 'X'] = 5


有人告诉我,不仅要重复,而且要使用幻数,应避免使用。

我想编写一个函数来有效地进行填充。

最佳答案

使用groupbytransform
转换看起来像

df.groupby('Y').X.transform('median')

0     7.5
1     7.5
2     7.5
3    12.5
4    12.5
5    12.5
6     5.0
7     5.0
8     5.0
9     5.0
Name: X, dtype: float64


并且它具有与以前相同的索引。因此,我们可以轻松地将其用于fillna

df.X.fillna(df.groupby('Y').X.transform('median'))

0    10.0
1     5.0
2     7.5
3    12.0
4    13.0
5    12.5
6     5.0
7     5.0
8     5.0
9     6.0
Name: X, dtype: float64


您可以创建数据框的新副本

df.assign(X=df.X.fillna(df.groupby('Y').X.transform('median')))

   Y     X
0  a  10.0
1  a   5.0
2  a   7.5
3  b  12.0
4  b  13.0
5  b  12.5
6  c   5.0
7  c   5.0
8  c   5.0
9  c   6.0


或适当的fillna

df.X.fillna(df.groupby('Y').X.transform('median'), inplace=True)
df

   Y     X
0  a  10.0
1  a   5.0
2  a   7.5
3  b  12.0
4  b  13.0
5  b  12.5
6  c   5.0
7  c   5.0
8  c   5.0
9  c   6.0

08-19 23:49