使用同一列中的样本填充缺失值

3

简单的数据框架示例:

df = pd.DataFrame({'mycol':['foo','bar','hello','there',np.nan,np.nan,np.nan,'foo'],
                  'mycol2':'this is here to make it a DF'.split()})
print(df)

   mycol mycol2
0    foo   this
1    bar     is
2  hello   here
3  there     to
4    NaN   make
5    NaN     it
6    NaN      a
7    foo     DF

我试图用 mycol 中的数据填充 NaN 值,例如我希望将 NaN 替换为 foobarhello 等样本。
# fill NA values with n samples (n= number of NAs) from df['mycol']

df['mycol'].fillna(df['mycol'].sample(n=df.isna().sum(), random_state=1,replace=True).values)

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

# fill NA values with n samples, n=1. Dropna from df['mycol'] before sampling:

df['mycol'] = df['mycol'].fillna(df['mycol'].dropna().sample(n=1, random_state=1,replace=True)).values

# nothing happens

预期输出:Nas填充了从mycol中随机抽样的数据。
   mycol mycol2
0    foo   this
1    bar     is
2  hello   here
3  there     to
4    foo   make
5    foo     it
6  hello      a
7    foo     DF

回答编辑: @Jezrael的下面的答案解决了我的问题,我在索引方面有问题。

df['mycol'] = (df['mycol'] 
               .dropna()
               .sample(n=len(df),replace=True) 
               .reset_index(drop=True))

n = df.isna().sum() 这部分是问题所在;检查一下,你会发现它给出了两个数字而不是一个。 - help-ukraine-now
你能在你的问题中添加期望的输出吗? - SM Abu Taher Asif
@Asif 添加到原始问题 - SCool
2个回答

3

有趣的问题。

对于我来说,使用loc设置值时,将值转换为numpy数组以避免数据对齐:

a = df['mycol'].dropna().sample(n=df['mycol'].isna().sum(), random_state=1,replace=True)
print (a)
3    there
7      foo
0      foo
Name: mycol, dtype: object

#pandas 0.24+
df.loc[df['mycol'].isna(), 'mycol'] = a.to_numpy()
#pandas below
#df.loc[df['mycol'].isna(), 'mycol'] = a.values
print (df)
   mycol mycol2
0    foo   this
1    bar     is
2  hello   here
3  there     to
4  there   make
5    foo     it
6    foo      a
7    foo     DF

如果 Series 和索引的长度与原始 DataFrame 相同,则您的解决方案应该能够正常工作:

s = df['mycol'].dropna().sample(n=len(df), random_state=1,replace=True)
s.index = df.index
print (s)
0    there
1      foo
2      foo
3      bar
4    there
5      foo
6      foo
7      bar
Name: mycol, dtype: object

df['mycol'] = df['mycol'].fillna(s)
print (df)

#   mycol mycol2
0    foo   this
1    bar     is
2  hello   here
3  there     to
4  there   make
5    foo     it
6    foo      a
7    foo     DF

1
这个变体也可以:df['mycol'] = df['mycol'].dropna().sample(n=len(df), random_state=1,replace=True).reset_index(drop=True),虽然只有一行,但看起来有点凌乱。 - SCool

1
你可以进行向前或向后填充:
#backward fill
df['mycol'] = df['mycol'].fillna(method='bfill')

#forward Fill
df['mycol'] = df['mycol'].fillna(method='ffill')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接