Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 根据groupby中的比例填充分类NaN值_Python 3.x_Pandas_Pandas Groupby - Fatal编程技术网

Python 3.x 根据groupby中的比例填充分类NaN值

Python 3.x 根据groupby中的比例填充分类NaN值,python-3.x,pandas,pandas-groupby,Python 3.x,Pandas,Pandas Groupby,我正在使用一个完全由分类特征组成的数据集 只有一列缺少值:8124列中有2480列 我可以根据现有分类值的百分比成功填充NaN值: print(df['stalk-root'].value_counts(normalize=True), '\n') 收益率: b 0.669029 e 0.198441 c 0.098512 r 0.034018 e b 0.550459 e 0.247706

我正在使用一个完全由分类特征组成的数据集

只有一列缺少值:8124列中有2480列

我可以根据现有分类值的百分比成功填充NaN值:

print(df['stalk-root'].value_counts(normalize=True), '\n')
收益率:

b    0.669029
e    0.198441
c    0.098512
r    0.034018
e      b             0.550459
       e             0.247706
       c             0.146789
       r             0.055046
p      b             0.860853
       e             0.118738
       c             0.020408
然后,我使用这些百分比来填充缺少的值:

# https://stackoverflow.com/questions/38934140/fill-missing-values-by-a-ratio-of-other-values-in-pandas
df['stalk-root'] = df['stalk-root'].fillna(pd.Series(np.random.choice(['b', 'e', 'c', 'r'],
                                                     p=[0.669029, 0.198441, 0.098512, 0.034018], size=len(df))))
它工作得很好

然而,我很好奇,如果我按“class”列分组,df['stack-root']列的值_计数会是什么样子

print(df.groupby('class')['stalk-root'].value_counts(normalize=True), '\n')
收益率:

b    0.669029
e    0.198441
c    0.098512
r    0.034018
e      b             0.550459
       e             0.247706
       c             0.146789
       r             0.055046
p      b             0.860853
       e             0.118738
       c             0.020408
这是一个相当大的区别。足够大,我现在想将我的NaN填充过程修改为第一个 按类别分组,然后按百分比填充,如上所述

我以前用数值列和mean()做过这项工作,但不同之处在于我是手动完成的 根据值_计数的结果(normalize=True),在np.random.choice()中填充百分比

我不知道该怎么说:groupby类,运行['stape-root'].value\u counts(normalize=True),然后获取这些值并输入fillna(np.random.choice(),就像我上面做的那样

我将有两组完全不同的填充值,“r”只出现在其中一个中

一个是(对于“e”类):

另一个(对于“p”类)为:

我遇到的第二个问题是size=len(df)。这必须是每个分组的大小(我假设),并且它们的大小不同


也许我误解了,但你不能这样做:

class_e = pd.Series(np.random.choice(['b', 'e', 'c', 'r'],
                   p=[0.550459, 0.247706, 0.146789, 0.055046], size=len(df)))
class_p = pd.Series(np.random.choice(['b', 'e', 'c'],
                   p=[0.860853, 0.118738, 0.020408], size=len(df))

df.loc[df['class'] == e, 'stalk-root'] = df['stalk-root'].fillna(class_e)
df.loc[df['class'] == p, 'stalk-root'] = df['stalk-root'].fillna(class_p)

下面是一个使用
groupby

was_null = df['stalk-root'].isna()

for _, gdf in df.groupby('class')['stalk-root']:
    vc = gdf.value_counts(normalize=True)
    df.loc[gdf.loc[gdf.isna()].index, 'stalk-root'] = (
        np.random.choice(vc.index, gdf.isna().sum(), p=vc)
    )
验证输出

# old distribution
print(df[was_null].groupby('class')['stalk-root'].value_counts(normalize=True))

class  stalk-root
e      b             0.561111
       e             0.236111
       c             0.140278
       r             0.062500
p      b             0.865341
       e             0.117045
       c             0.017614
Name: stalk-root, dtype: float64


# new distribution
print(df.groupby('class')['stalk-root'].value_counts(normalize=True))

class  stalk-root
e      b             0.552281
       e             0.245722
       c             0.145675
       r             0.056321
p      b             0.862870
       e             0.117978
       c             0.019152
Name: stalk-root, dtype: float64

你能提供一个例子吗?比如说
df[['class','stable root']]].head(50)。为了_dict()
@RichieV,我必须编辑我的问题以适应你要求的输出。见上文。我使用的是Kaggle的蘑菇.csv数据集。该数据集中没有
NaN
s…下载后你修改了吗?
df.info()
数据集中没有空值。
范围索引:8124个条目,0到8123
&所有列都有
8124个非空值
valuese_size=df[df['class']==e,:].size。如果我使用
e_size=len(df[df['class']='e'])
错误已解决,但结果不正确。您的初始解决方案似乎是正确的。它必须在整个df中循环,因为受影响的行可能位于任何位置。起初我没有意识到。如果您修改的解决方案包含在groupby()中对象,那么我认为它是正确的。我甚至可以通过注释掉
df.loc[df['class']==e,'stable root']]
行,一次一行,来查看第一个解决方案的每个部分到底填充了多少行。抱歉,我不太明白。如果你想在groupby@RichieV的解决方案中使用它,应该接受:)这对我来说无关紧要。你最初的解决方案很有效。删除编辑以将初始解决方案放回原位。