2017-07-02 68 views
1

我有一个熊猫数据框,其中一列sign up有多个空值。该sign up柱具有包括多个OSiOSandroidweb等 我想从现有OS值但NA值填补NA值应该被填充为每OS值的现有的分配分类值。熊猫:根据现有值的分布填充NA值要填充

实施例: 可以说,该数据集具有OS的值计数的分布如下:

signup 
android web 14 
ios web  16 
mac   5 
other   3 
windows  6 
Name: id, dtype: int64 

我想补基于所述不同的OS的值的上述分布的NA值。我想要做的原因是保持目前的分布,因为填充价值可能会扭曲结果。 有人可以帮助如何做到这一点。

回答

4

你可以使用的东西,像NumPy这样的random.choice

开始使用piRSquared的小费在评论 帧适合您的描述

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 

更新搞清楚的电流分布

s = df.signup.value_counts(normalize=True) 
print(s) 
windows 0.444444 
mac  0.333333 
other  0.222222 
Name: signup, dtype: float64 

我们将在f旁边使用布尔索引ilter由我们想要更新的nans。此外,这是我们通过传递索引(窗口,mac,其他),所需大小以及每个注册的分布将用于概率(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 
+0

好像我们不明白的问题,以同样的方式,他的注册列是一个与NaN值? –

+1

感谢鲍勃。这很有帮助。 – user4943236

+1

'df.signup.value_counts(normalize = True)' – piRSquared

1

首先,我把这个作为输入(因为我觉得你的问题,你错名为my valuesign 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的

01。

但如果你想你的输出与同列的数据框名称进行如下操作:

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 
1
  • 找到空
  • 样本来自非空值的空值。请务必将replace=True
  • 分配采样值为null位置

isnull = df.signup.isnull() 
sample = df.signup.dropna().sample(isnull.sum(), replace=True).values 
df.loc[isnull, 'signup'] = sample