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

时间:2018-05-09 18:19:31

标签: python pandas dataframe

我在这里看过thisthis帖子,但其他错误。

我有一个非常大的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值应该计为Na(对于isnull()和fillna(),或者不计算任何一个)。为什么它看起来是由isnull()而不是fillna()计算的?

1 个答案:

答案 0 :(得分: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())