为啥在数据帧上具有中位数的 fillna 仍然在熊猫中留下 Na/NaN?

Posted

技术标签:

【中文标题】为啥在数据帧上具有中位数的 fillna 仍然在熊猫中留下 Na/NaN?【英文标题】:Why does fillna with median on dataframe still leaves Na/NaN in pandas?为什么在数据帧上具有中位数的 fillna 仍然在熊猫中留下 Na/NaN? 【发布时间】:2018-10-19 22:48:06 【问题描述】:

我在这里看到了this 和this 线程,但还有其他问题。

我有一个非常大的 pandas DataFrame,其中包含许多 Na/NaN 值。我想用该特征的中值替换它们。

所以,我首先制作一个表格,显示每个特征的 Na 值,按大多数 Na 值排序,然后使用 fillna(),然后再次显示该表格。理想情况下,第二次该表应该全为 0,因为所有的 Na 都已填满。

nullCount = pd.DataFrame(TT_df.isnull().sum(),columns=["nullcount"]).sort_values(by="nullcount",ascending=False)
display(nullCount.head(10))

TT_df = TT_df.fillna(TT_df.median())

nullCount = pd.DataFrame(TT_df.isnull().sum(),columns=["nullcount"]).sort_values(by="nullcount",ascending=False)
display(nullCount.head(10))

但是,我得到了这两个表:

null count tables, before and after

如果我看一下 DataFrame,你可以在其中看到 NaN:

display(TT_df[nullCount.index.tolist()[0:5]].head(50))

NaN examples

fillna() 的一个常见问题似乎是它返回一个副本,除非您使用 inplace=True(如上面链接的线程中),但我这样做:我正在覆盖 TT_df,除非我误解了什么。您可以看到 LotFrontage 功能实际上确实从第二个表中消失了,这意味着 fillna() 确实 为它工作。那么为什么它对其他人不起作用呢?

我怀疑是罪魁祸首,虽然我不知道为什么,但对于这些功能,Na 实际上并不意味着 Na:如果我查看数据描述文件,它会说:

GarageFinish:车库的内部装修

   Fin    Finished
   RFn    Rough Finished  
   Unf    Unfinished
   NA No Garage

好的,没关系。但感觉这些 NA 值应该对 isnull() 和 fillna() 都算作 Na,或者不算作任何一个。为什么它似乎被 isnull() 计数而不是 fillna()?

【问题讨论】:

那个 NA 实际上是一个字符串吗? @cᴏʟᴅsᴘᴇᴇᴅ 如果我显示(TT_df.iloc[17]["BsmtExposure"]),它返回 nan... 但如果我显示(type(TT_df.iloc[17][" BsmtExposure"])),它说浮动... 所以,我不知道你的问题是什么,除非你能帮我重现它。 【参考方案1】:

问题出在这一行:

TT_df = TT_df.fillna(TT_df.median())

您的数据框有字符串,您正在尝试计算字符串的中位数。这不起作用。

这是一个最小的例子:

import pandas as pd, numpy as np

df = pd.DataFrame('A': ['A', 'B', np.nan, 'B'])

df = df.fillna(df.median())

print(df)

     A
0    A
1    B
2  NaN
3    B

你应该做的是fillna,中位数只用于数字列:

for col in df.select_dtypes(include=np.number):
    df[col] = df[col].fillna(df[col].median())

【讨论】:

天啊!谢谢,这是有道理的。出于某种原因,我愚蠢地认为它正在用 mode 代替它,但显然不是这样。这对非数字特征来说是一个合理的“填充物”吗?此外,人们通常用中位数而不是平均值填充数字 Na 是否有充分的理由?谢谢! @GrundleMoof, 不,mode 也仅适用于数字列。 medianmean 应根据您使用数据的方式逐个选择。 @jpp 这是选择meanmedian 的一种非常聪明的方式。即使是mode

以上是关于为啥在数据帧上具有中位数的 fillna 仍然在熊猫中留下 Na/NaN?的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas Fillna 中位数不起作用

为啥 numpy 函数在 pandas 系列/数据帧上这么慢?

在 Pandas 中具有向后和向前看状态的 Fillna

在具有多个参数的 pandas 数据帧上应用滚动函数

Pandas:具有多索引的 fillna() 方法 - NaN 填充了错误的列

python - Pandas - FillNa 与另一个具有相似列的非空行