给出一个包含两列的数据框,如下所示:
| user_id | preference_id |
|---------|---------------|
| 1 | 1 |
| 1 | 2 |
| 1 | None |
| 2 | 1 |
| 3 | 2 |
| 3 | 2 |
| 3 | None |
如何用preference_id
的最频繁值填充user_id
中的缺失值?我当前的解决方案包括使用数据循环遍历所有唯一的user_id
,这些preference_id
至少具有一个缺失值,而preference_id
的至少一个实例具有数据:
# Find all rows where preference_id is missing
pref_na = df.loc[df.preference_id.isna()]
# Find all users that have at least one missing and one not missing
# value for preference_id
users = df.loc[
(~df.preference_id.isna()) & (df.user_id.isin(pref_na))
]
for id in users.user_id.unique():
# Find most common preference_id for a user
top_pref = df.loc[
(df.user_id == id) & (~df.preference_id.isna()),
['preference_id']
]
if top_pref.shape[0] == 0:
continue
top_pref = top_pref.preference_id.mode()[0]
# Fill in missing prefs with top_pref
df.loc[
(df.user_id == id) & (df.preference_id.isna()),
'preference_id'] = top_pref
是否有一种本机或矢量化方式来完成此任务?
在此示例中,@ anky_91的建议中断了:
df = pd.DataFrame({
'user_id': [1, 1, 1, 2, 3, 3, 3],
'preference_id': [1, 2, None, None, 2, 2, None]
})
也就是说,user_id
个记录中只有一个丢失了preference_id
s
在尝试了@ anky_91的解决方案之后,我能够通过首先过滤掉只有缺失值的用户(因此,我无法推断出缺失的preference_id的用户)来解决上述的极端情况:>
# Remove edge cases
ids = df.groupby('user_id').preference_id.count()\
.where(lambda x: x > 0).dropna().to_frame().reset_index()
# User anky_91 solution
ids.groupby('user_id').preference_id.transform(lambda x: x.mode().iat[0])
可能会有一种更高效,更优雅的方法来进行第一步,但是那样的话。最慢的部分是第二步,所以我可以接受步骤1的形式。
答案 0 :(得分:2)
使用:
s=df.groupby('user_id')['preference_id'].transform(lambda x: x.mode().iat[0])
df.preference_id=df.preference_id.fillna(s)
print(df)
user_id preference_id
0 1 1.0
1 1 2.0
2 1 1.0
3 2 1.0
4 3 2.0
5 3 2.0
6 3 2.0
另一种方式:
m=(df.groupby('user_id')['preference_id'].apply(lambda x: x.mode(dropna=False).iat[0])
.reset_index(name='Mode'))
df.merge(m,on='user_id')
user_id preference_id Mode
0 1 1.0 1.0
1 1 2.0 1.0
2 1 NaN 1.0
3 2 NaN NaN
4 3 2.0 2.0
5 3 2.0 2.0
6 3 NaN 2.0