首页 > 解决方案 > 尝试用 fillna() 和 groupby() 填充 NaN

问题描述

所以我基本上有一个包含几列的 Airbnb 数据集。其中一些对应于不同参数(清洁度、位置等)的评级。对于这些列,我有一堆要填充的 NaN。

由于其中一些 NaN 对应于来自同一所有者的列表,因此我想在其中一些 NaN 中填充相应主机对这些列中的每一列的平均评分。

例如,假设对于主机 X,review_scores_location 的平均值为 7。我要做的是,在 review_scores_location 列中,将主机 X 对应的所有 NaN 值填充为 7。

我试过以下代码:

cols=['reviews_per_month','review_scores_rating','review_scores_accuracy','review_scores_cleanliness','review_scores_checkin','review_scores_communication','review_scores_location','review_scores_value']

for i in cols:
  airbnb[i]=airbnb[i].fillna(airbnb.groupby('host_id')[i].mean())

虽然它确实运行并且它没有返回任何错误,但它不会填充 NaN 值,因为当我检查是否还有任何 NaN 时,数量没有改变。

我在做什么?

感谢您抽时间阅读!

标签: pythonpandasgroup-bynan

解决方案


这里的问题是,当在 中使用系列airbnb.groupby('host_id')[i].mean()fillna,函数会尝试对齐索引,并且由于索引airbnb.groupby('host_id')[i].mean()实际上是列的值host_id而不是 的原始索引值airbnb,因此fillna无法按预期工作。有几个选项可以完成这项工作,一种方法是使用transformaftergroupby将每个组的值与原始索引值对齐mean,然后fillna按预期工作,例如:

for i in cols:
    airbnb[i]=airbnb[i].fillna(airbnb.groupby('host_id')[i].transform('mean'))

甚至,您可以在没有循环的情况下使用此方法,例如:

airbnb = airbnb.fillna(airbnb.groupby('host_id')[cols].transform('mean'))

举个例子:

airbnb = pd.DataFrame({'host_id':[1,1,1,2,2,2], 
                       'reviews_per_month':[4,5,np.nan,9,3,5],
                       'review_scores_rating':[3,np.nan,np.nan,np.nan,7,8]})
print (airbnb)
   host_id  review_scores_rating  reviews_per_month
0        1                   3.0                4.0
1        1                   NaN                5.0
2        1                   NaN                NaN
3        2                   NaN                9.0
4        2                   7.0                3.0
5        2                   8.0                5.0

你得到:

cols=['reviews_per_month','review_scores_rating'] # would work with all your columns
print (airbnb.fillna(airbnb.groupby('host_id')[cols].transform('mean')))
   host_id  review_scores_rating  reviews_per_month
0        1                   3.0                4.0
1        1                   3.0                5.0
2        1                   3.0                4.5
3        2                   7.5                9.0
4        2                   7.0                3.0
5        2                   8.0                5.0

推荐阅读