使用groupby和pd.isnull在Pandas系列上应用自定义函数

时间:2016-09-07 18:51:42

标签: python pandas

我有一个样本数据框,通常如下所示:

df = pd.Dataframe({'Class': [1, 2, 3, 2, 1, 2, 3, 2],
                   'Sex': [1, 0, 0, 0, 1, 1, 0, 1],
                   'Age': [15, 24, 13, 28, 29, NaN, 34, 27]})

显示为:

    Age  Class  Sex
0  15.0      1    1
1  24.0      2    0
2  13.0      2    0
3  28.0      2    0
4  29.0      1    1
5   NaN      2    1
6  34.0      1    0
7  27.0      2    1

我想要做的是在'Age'系列中填写每个NaN值,其中包含所有具有'Class'和'Sex'分组的条目的中值。

例如,当我像这样访问这些值时:

df.groupby(['Class', 'Sex'])['Age'].median()

并获得:

  Class  Sex
   1      0      34.0
          1      22.0
   2      0      24.0
          1      27.0

我想编写一个自动填充现有NaN值27的函数,因为那是Class值为2且Sex值为1的条目的中位数。

现在我有:

df['Age'] = df.groupby(['Class', 'Sex'])['Age'].apply(lambda x: x.median() if pd.isnull(x) else x)

我收到以下错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

然而,在this questionthis one的答案中使用了非常相似的语法,所以我不太清楚为什么我的不起作用,特别是后者也使用isnull方法在它的lambda函数中,所以我不清楚为什么我的工作不起作用,但是那个人没有。

我也尝试过使用fillna方法:

df['Age'] = df['Age'].fillna(df.groupby(['Class', 'Sex'])['Age'].median())

但收到以下错误消息:

ValueError: Buffer dtype mismatch, expected 'Python object' but got 'long long'

我对其他获得相同值的方法持开放态度,但更喜欢完全依赖Pandas方法的东西,而不必使用单独的for循环并将其传递给'Apply'方法,以使其尽可能简洁

谢谢。

1 个答案:

答案 0 :(得分:2)

一种选择是使用transform将空值替换为Age列的中位数:

df['Age'] = df.groupby(['Class', 'Sex']).Age.transform(lambda col: col.where(col.notnull(), col.median()))

df

#   Age Class   Sex
#0  15.0    1   1
#1  24.0    2   0
#2  13.0    3   0
#3  28.0    2   0
#4  29.0    1   1
#5  27.0    2   1
#6  34.0    3   0
#7  27.0    2   1

或者使用replace方法代替where也可以:

df['Age'] = df.groupby(['Class', 'Sex']).Age.transform(lambda col: col.replace(np.nan, col.median()))