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 的分类值,例如 iosandroidweb 等。 我想从现有的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 数据帧

如何在 Pandas Python 中为一组主键分组填充 NA 值

用 pandas 数据框中另一列的值填充多列中的 Na

熊猫:用组的模式填充na