Pandas 是否用过滤器的最常用值填充缺失值?

Pandas 是否用过滤器的最常用值填充缺失值?,pandas,dataframe,data-science,Pandas,Dataframe,Data Science,给定一个包含两列的数据帧,如下所示: | user_id | preference_id | |---------|---------------| | 1 | 1 | | 1 | 2 | | 1 | None | | 2 | 1 | | 3 | 2 | | 3 | 2 | | 3

给定一个包含两列的数据帧,如下所示:

| user_id | preference_id |
|---------|---------------|
| 1       | 1             |
| 1       | 2             |
| 1       | None          |
| 2       | 1             |
| 3       | 2             |
| 3       | 2             |
| 3       | None          |
如何用该
用户id
的最频繁值来填充
首选项id
中缺少的值?我当前的解决方案包括在所有唯一的
用户id
上循环,这些用户id至少有一个
首选项id
缺少值,并且至少有一个
首选项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]
})
也就是说,其中一个
用户id
记录只缺少
首选项id
s

编辑#2 在使用@anky_91的解决方案进行试验后,我能够通过首先过滤掉只有缺失值的用户(因此,我无法推断缺失的偏好id的用户)来解决上面发布的边缘情况:

可能有一种更高效、更优雅的方法来完成第一步,但这样就可以了。缓慢的部分是第二步,因此我同意第1步的形式。

使用:

s=df.groupby('user_id')['preference_id'].transform(lambda x: x.mode().iat[0])
df.preference_id=df.preference_id.fillna(s)
print(df)

另一种方式:

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')


如果有两个(或更多)最常见的值怎么办?
top\u pref=top\u pref.preference\u id.mode()[0]
如果有多个相同频率的pref,我只取其中的一个。这没关系,这看起来很有希望。但是,发送到lambda的值似乎是一个带有单个
首选项\u id
的序列。在某些情况下,给定的
user\u id
有5个pref值,只有一个pref值为
nan
,但lambda正好传递给
nan
,因此
x.mode().iat[0]
返回
索引0超出大小为0的轴0的界限。
@rodrigo silveira it Group
user\u id
,你能用一个例子详细说明这一点吗?贴了一个例子
   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