熊猫填充模式
Posted
技术标签:
【中文标题】熊猫填充模式【英文标题】:How to Pandas fillna() with mode of column? 【发布时间】:2017-08-04 23:39:20 【问题描述】:我有一个数据集,其中有一个名为 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
值。
【问题讨论】:
你能发布原始数据、创建df的代码和你观察到的输出data['Native Country'].mode()
返回一个系列对象。要访问它的第一个值,您需要在 fillna
操作期间包含 .iloc[0]
。另请注意,如果该列中没有至少 2 次重复出现,NaN's
将不会被替换。
【参考方案1】:
只需调用系列的第一个元素:
data['Native Country'].fillna(data['Native Country'].mode()[0], inplace=True)
或者你也可以对分配做同样的事情:
data['Native Country'] = data['Native Country'].fillna(data['Native Country'].mode()[0])
【讨论】:
当然需要像mode()[0]
那样对单个数据列使用[0]
进行切片是一个错误:mode()
即使在系列上调用也假定一个DataFrame)。它应该像 mean()
一样工作,在 Series 上调用时返回单个浮点数,在 DataFrame 上调用时返回 Series ...不同行为的唯一理由是涵盖多模式分布。
很晚了。但是我有一个数据框,可以在其中合并多个数据库。有一个区域我必须使用分配方面或者我得到一个多索引警告,然后我运行一个函数来将这个系列与其他系列进行比较,我必须只使用 fillna(inplace=True) 或者一切都会改变而不是只是NaN。我不知道为什么【参考方案2】:
小心,NaN 可能是您的数据框的模式:在这种情况下,您将 NaN 替换为另一个 NaN。
【讨论】:
Pandas 0.24.0+ 默认不计算 NaN:pandas.pydata.org/pandas-docs/stable/reference/api/…【参考方案3】:如果我们用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, 21, 99]
作为同样最频繁的值,则仅采用 0
。或者当True
和False
值在给定列中的频率相同时,用False
填充缺失值。
我在这里没有明确的解决方案。如果必须使用该模式,则从所有局部最大值中分配一个随机值可能是一种方法。
【讨论】:
【参考方案4】:尝试类似:
fill_mode = lambda col: col.fillna(col.mode())
和功能:
new_df = df.apply(fill_mode, axis=0)
【讨论】:
【参考方案5】:您可以获取数字“模式”或任何其他策略
-
对于模式:
num = data['Native Country'].mode()[0]
data['Native Country'].fillna(num, inplace=True)
-
平均值、中位数:
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)
【讨论】:
【参考方案6】: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])
Country | Purchased | |
---|---|---|
0 | NaN | NaN |
1 | France | Yes |
2 | NaN | Yes |
3 | Spain | No |
4 | France | NaN |
df.fillna(df.mode()) ## only applied on first row because df.mode() returns a dataframe with one row
Country | Purchased | |
---|---|---|
0 | France | Yes |
1 | France | Yes |
2 | NaN | Yes |
3 | Spain | No |
4 | France | 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
Country | Purchased | |
---|---|---|
0 | France | Yes |
1 | France | Yes |
2 | France | Yes |
3 | Spain | No |
4 | France | Yes |
【讨论】:
【参考方案7】:对于那些来到这里(就像我一样)在多列中填充 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 语句返回模式并返回组的 NA,其中只有 NA。
【讨论】:
以上是关于熊猫填充模式的主要内容,如果未能解决你的问题,请参考以下文章