Pandas:根据现有值的分布填充要填充的NA值
Posted
技术标签:
【中文标题】Pandas:根据现有值的分布填充要填充的NA值【英文标题】:Pandas: Filling NA values to be filled based on distribution of existing values 【发布时间】:2017-12-05 15:20:25 【问题描述】:我有一个 pandas 数据框,其中一列 sign up
有多个空值。 sign up
列具有包含多个 OS
的分类值,例如 ios
、android
、web
等。
我想从现有的OS
值中填充NA
值,但应根据OS
值的现有分布填充NA 值。
示例: 可以说,数据集的 OS 值计数分布如下:
signup
android web 14
ios web 16
mac 5
other 3
windows 6
Name: id, dtype: int64
我想根据上述不同 OS 值的分布来填充 NA 值。我想做的原因是保持当前分布,因为填充Mode
值可能会扭曲结果。
有人可以帮助如何实现这一目标。
【问题讨论】:
【参考方案1】:你可以使用类似 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
更新在 cmets 中使用 piRSquared 的提示 弄清楚当前的分布
s = df.signup.value_counts(normalize=True)
print(s)
windows 0.444444
mac 0.333333
other 0.222222
Name: signup, dtype: float64
接下来我们将使用布尔索引来过滤我们想要更新的 nan。此外,这是我们通过传递索引(windows、mac 和其他)来使用随机选择的地方,所需的大小和每个注册的分布将用于 probabilities(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
【讨论】:
似乎我们没有以同样的方式理解问题,他的注册栏是具有 NaN 值的栏? 谢谢鲍勃。这很有帮助。df.signup.value_counts(normalize=True)
超级有帮助的@Bob【参考方案2】:
查找空值
从非空值中抽取空值的数量。确保设置replace=True
将采样值分配给空位置
isnull = df.signup.isnull()
sample = df.signup.dropna().sample(isnull.sum(), replace=True).values
df.loc[isnull, 'signup'] = sample
【讨论】:
【参考方案3】:首先,我将此作为输入(因为我认为在您的问题中您错误地将我的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
【讨论】:
以上是关于Pandas:根据现有值的分布填充要填充的NA值的主要内容,如果未能解决你的问题,请参考以下文章
Python、Pandas 和 for 循环:根据与列表值的匹配填充数据框行
(pandas) 根据 groupby 和 column 条件填充 NaN
用 NA 值填充 dict 以允许转换为 pandas 数据帧