我有一个pandas数据框,其中一列sign up
有多个空值。 sign up
列的分类值包含多个OS
,例如iOS
,android
,web
等。
我想填充现有NA
值中的OS
值,但应根据OS
值的现有分布填充NA值。
实施例: 可以说,数据集的OS值计数分布如下:
signup
android web 14
ios web 16
mac 5
other 3
windows 6
Name: id, dtype: int64
我想根据不同OS值的上述分布来填充NA值。我想要做的是保持当前分布,因为填充Mode
值可能会导致结果偏差。
有人可以帮助解决这个问题。
答案 0 :(得分:8)
你可以使用Numpy的random.choice
之类的东西从符合您描述的框架开始
import numpy as np
import pandas as pd
print(df)
id signup
0 1 mac
1 2 mac
2 3 mac
3 4 other
4 5 other
5 6 windows
6 7 windows
7 8 windows
8 9 windows
9 10 NaN
10 11 NaN
11 12 NaN
12 13 NaN
13 14 NaN
在评论中使用piRSquared的提示更新了 搞清楚目前的分布情况
s = df.signup.value_counts(normalize=True)
print(s)
windows 0.444444
mac 0.333333
other 0.222222
Name: signup, dtype: float64
我们将在我们想要更新的nans过滤器旁边使用布尔索引。此外,我们通过传递索引(windows,mac,other)来使用随机选择,所需的大小和每个注册的分布将用于概率(p)参数。
missing = df['signup'].isnull()
df.loc[missing,'signup'] = np.random.choice(s.index, size=len(df[missing]),p=s.values)
print(df)
id signup
0 1 mac
1 2 mac
2 3 mac
3 4 other
4 5 other
5 6 windows
6 7 windows
7 8 windows
8 9 windows
9 10 windows
10 11 windows
11 12 mac
12 13 windows
13 14 other
答案 1 :(得分:1)
首先,我将此作为输入(因为我认为您在问题中错误地命名了我的value
列sign up
:
signup value
0 android web 14.0
1 ios web 16.0
2 mac 5.0
3 other 3.0
4 windows 6.0
5 ios web NaN
6 mac NaN
7 windows NaN
知道这个问题可以在一行中解决如下:
b = df.groupby('signup')['value'].first()[df['signup']]
请注意,b
的类型为pandas.Series。
但如果您希望输出为具有相同列名称的DataFrame,请按以下步骤操作:
b = pd.DataFrame(df.groupby('signup')['value'].first()[df['signup']],columns=['value']).reset_index()
b.rename({1:'value'})
如果您print(b)
,则输出:
signup value
0 android web 14.0
1 ios web 16.0
2 mac 5.0
3 other 3.0
4 windows 6.0
5 ios web 16.0
6 mac 5.0
7 windows 6.0
答案 2 :(得分:1)
replace=True
isnull = df.signup.isnull()
sample = df.signup.dropna().sample(isnull.sum(), replace=True).values
df.loc[isnull, 'signup'] = sample