如何用现有的列值替换DataFrame列的NaN值?

时间:2019-07-31 07:36:01

标签: pandas pandas-groupby

样本数据帧df:

  EateryItem
0 Burger
1 pizza
2 Donut
3 NaN
4 NaN
5 NaN
6  .
.  .
.  .
15 NaN

要填充前面的项目,我找到了解决方法

df.bfill().ffill()

我的预期结果是用现有的列值填充NaN(不一定相同的顺序,也可能是随机的):

EateryItem
0 Burger
1 pizza
2 Donut
3 Burger
4 pizza
5 Donut
6 Burger
7 pizza
8 Donut
9 Burger
10 pizza
11 Donut
.   .
.   . 

3 个答案:

答案 0 :(得分:1)

您可以: 通过np.random.choice创建一个随机数组,从非NaN元素到NaN元素的长度:int(df.EateryItem.isna().sum()),然后使用df.loc,过滤{{1} }元素并分配此数组

NaN

s=np.random.choice(df.EateryItem.dropna(),int(df.EateryItem.isna().sum()))
df.loc[df.EateryItem.isna(),'EateryItem']=s
print(df)

答案 1 :(得分:1)

使用pandas.DataFrame.sampleEateryItem中随机抽取项目样本

values_to_fill = df['EateryItem']\
                .dropna()\
                .sample(n=df['EateryItem'].isna().sum(), random_state=1,replace=True)

df.loc[df['EateryItem'].isna(), 'EateryItem'] = values_to_fill.to_numpy()
    EateryItem
0   Burger
1   pizza
2   Donut
3   pizza
4   Burger
5   Burger
6   pizza
...

编辑

dropna返回仅包含有效值的pandas.core.series.Series

df['EateryItem'].dropna()
# 0    Burger
# 1     pizza
# 2     Donut
# Name: EateryItem, dtype: object

从这些值中我想获得一个随机样本,所以我使用.sample

df['EateryItem'].dropna()\
                .sample(n=df['EateryItem'].isna().sum(), random_state=1,replace=True)

# 1     pizza
# 0    Burger
# 0    Burger
# 1     pizza
# Name: EateryItem, dtype: object

n这里有许多要退货的物品。在这种情况下,我需要一个等于所有缺失值之和的数字,因此.isna().sum()

df['EateryItem'].isna().sum()
# 4

random_state=1是种子,并且为了提高可重复性而添加(可以省略)。

replace指定是否替换样本。如果默认值为False,则会引发错误:ValueError: Cannot take a larger sample than population when 'replace=False'

使用.to_numpySeries的值转换为数组,得到:

values_to_fill.to_numpy()

# array(['pizza', 'Burger', 'Burger', 'pizza'], dtype=object)

现在我有了一个包含项的数组,我可以使用它们来填充原始Series中的缺失值。

df.loc[df['EateryItem'].isna(), 'EateryItem'] = values_to_fill.to_numpy()

.isna.loc结合使用,我过滤了缺少值的行:

df.loc[df['EateryItem'].isna()]

#   EateryItem
# 3 NaN
# 4 NaN
# 5 NaN
# 6 NaN

此后,我指定要使用数组values_to_fill.to_numpy()... , 'EateryItem'] = values_to_fill.to_numpy()替换上面的缺失值。

答案 2 :(得分:1)

我尝试过

s = df.item.dropna().unique().tolist()
m = df.item.isnull()
temp = s*int(len(df)/len(s))
temp = temp[:len(df[m])]
df.loc[m, 'item'] = temp

O / P:

      item
0   burger
1    pizza
2    donut
3   burger
4    pizza
5    donut
6   burger
7    pizza
8    donut
9   burger
10   pizza
11   donut
12  burger
13   pizza
14   donut

注意:这也将维持顺序:)