如何使用Pandas fillna()和列的模式?

vd8tlhqk  于 2023-04-04  发布在  其他
关注(0)|答案(8)|浏览(147)

我有一个数据集,其中有一个名为“Native Country”的列,其中包含大约30000条记录。有些缺失由NaN表示,因此我想用mode()值填充它。我写了这样的内容:

data['Native Country'].fillna(data['Native Country'].mode(), inplace=True)

但是,当我对缺失值进行计数时:

for col_name in data.columns: 
    print ("column:",col_name,".Missing:",sum(data[col_name].isnull()))

它仍然为列Native Country提供相同数量的NaN值。

yr9zkbsy

yr9zkbsy1#

只需要调用系列的第一个元素:

data['Native Country'].fillna(data['Native Country'].mode()[0], inplace=True)

或者你可以用assignment做同样的事情:

data['Native Country'] = data['Native Country'].fillna(data['Native Country'].mode()[0])
mqxuamgl

mqxuamgl2#

请注意,NaN可能是您的 Dataframe 的模式:在本例中,您将用另一个NaN替换NaN。

5uzkadbs

5uzkadbs3#

import numpy as np

import pandas as pd

print(pd.__version__)

1.2.0

df = pd.DataFrame({'Country': [np.nan, 'France', np.nan, 'Spain', 'France'], 'Purchased': [np.nan,'Yes', 'Yes', 'No', np.nan]})
国家采购
0NaNNaN
1法国是的
第二章NaN是的
西班牙不想
法国NaN
df.fillna(df.mode())  ## only applied on first row because df.mode() returns a dataframe with one row
国家采购
0法国是的
1法国是的
第二章NaN是的
西班牙不想
法国NaN
df = pd.DataFrame({'Country': [np.nan, 'France', np.nan, 'Spain', 'France'], 'Purchased': [np.nan,'Yes', 'Yes', 'No', np.nan]})

df.fillna(df.mode().iloc[0]) ## convert df to a series
国家采购
0法国是的
1法国是的
第二章法国是的
西班牙不想
法国是的
0yycz8jy

0yycz8jy4#

如果我们用fillna(df['colX'].mode())填充缺失值,因为mode()的结果是一个Series,它只会填充匹配索引的前几行。至少如果按照下面的方式完成:

fill_mode = lambda col: col.fillna(col.mode())
df.apply(fill_mode, axis=0)

然而,通过简单地取序列fillna(df['colX'].mode()[0])的第一个值,我认为我们有可能在数据中引入意外的偏差。如果样本是多模态的,只取第一个模态值会使已经有偏差的插补方法变得更糟。例如,只取0,如果我们有[0, 21, 99]作为同样最频繁的值。或者当TrueFalse值在给定列中出现的频率相等时,使用False填充缺失值。
我在这里没有一个明确的解决方案。如果使用模式是必要的,从所有局部最大值中分配一个随机值可能是一种方法。

eufgjt7s

eufgjt7s5#

你可以得到数字'模式'或任何其他策略
1.对于模式:

num = data['Native Country'].mode()[0]
    data['Native Country'].fillna(num, inplace=True)

1.平均值、中位数:

num = data['Native Country'].mean() #or median(); No need of [0] because it returns a float value.
    data['Native Country'].fillna(num, inplace=True)

或者像这样的一行

data['Native Country'].fillna(data['Native Country'].mode()[0], inplace=True)
yruzcnhs

yruzcnhs6#

对于那些来到这里(就像我一样)在多列中填充NA,按多列分组并且遇到模式不返回任何内容的问题的人,其中组中只有NA值:

df[['col_to_fill_NA_1','col_to_fill_NA_2']] = df.groupby(['col_to_group_by_1', 'col_to_group_by_2'], dropna=False)[['col_to_fill_NA_1','col_to_fill_NA_2']].transform(lambda x: x.fillna(x.mode()[0]) if len(x.mode()) == 1 else x)

你可以填充任意数量的“col_to_fill_NA”,并通过任意数量的“col_to_group_by”进行分组。if语句返回mode,如果mode存在,并返回组的NA,其中只有NA。

1u4esq0p

1u4esq0p7#

因此,我注意到df.mean()返回pd.Series,而df.mode在混合类型(在我的例子中是数字和分类)的数据集上调用时返回pd.DataFrame,其列与df相同,第0行给出了模式。这是预期的,因为Series的类型必须是唯一的,但仍然会导致df.fillna(df.mode())df.fillna(df.mean())工作时失败。
下面是一个简单的代码来解决这种情况下的问题:

df.fillna({k: v[0] for k, v in df.mode().to_dict().items()})

另一个问题仍然是第一个值v[0]是在可能的模式列表中选择的,如this answer所指出的,但是这仍然可以通过将另一个聚合函数应用于v来改进。

bvuwiixz

bvuwiixz8#

尝试以下内容:fill_mode = lambda col: col.fillna(col.mode()),对于函数:new_df = df.apply(fill_mode, axis=0)

相关问题