我刚开始学习Python,我想了解DataFrame中的执行过程。我们可以用kaggle.com上找到的数据集(泰坦尼克号:从灾难中学习机器学习)来举个例子。我想用各自性别的平均值替换NaN值,也就是说,男性NaN值应该用男性年龄的平均值替换,反之亦然。我通过使用以下代码实现了这一点:
_data['new_age']=_data['new_age'].fillna(_data.groupby('Sex')['Age'].transform('mean'))
我的问题是,在执行代码时,这行代码如何知道某一行属于男性,并且NaN值应该用男性的平均值替换,而女性的值应该用女性的平均值替换?
回答:
这是因为groupby
+ transform
。当你使用一个返回每个组标量值的聚合函数进行分组时,普通的groupby
会将每个独特的分组键压缩成一行。
np.random.seed(42)df = pd.DataFrame({'Sex': list('MFMMFFMMFM'), 'Age': np.random.choice([1, 10, 11, 13, np.NaN], 10)}, index=list('ABCDEFGHIJ'))df.groupby('Sex')['Age'].mean()#Sex#F 10.5 # 一行F#M 11.5 # 一行M#Name: Age, dtype: float64
使用transform
会根据行所属的组,将结果广播回原始索引。
df.groupby('Sex')['Age'].transform('mean')#A 11.5 # 属于M#B 10.5 # 属于F#C 11.5 # 属于M#D 11.5#E 10.5#F 10.5#G 11.5#H 11.5#I 10.5#J 11.5#Name: Age, dtype: float64
为了更清楚地说明,我将转换后的结果重新赋值,现在你可以看到.fillna
是如何得到正确的平均值的。
df['Sex_mean'] = df.groupby('Sex')['Age'].transform('mean')
Sex Age Sex_meanA M 13.0 11.5B F NaN 10.5 # NaN将被填充为10.5C M 11.0 11.5D M NaN 11.5 # NaN将被填充为11.5E F NaN 10.5 # NaN将被填充为10.5F F 10.0 10.5G M 11.0 11.5H M 11.0 11.5I F 11.0 10.5J M NaN 11.5 # NaN将被填充为11.5