我在这里看到了这个和这个线程,但还有其他问题。
我有一个非常大的熊猫数据帧,有很多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))
但是,我得到这两个表:
空计数表,之前和之后
如果我看一下数据帧,你可以看到其中的 NaN:
display(TT_df[nullCount.index.tolist()[0:5]].head(50))
纳米示例
似乎 fillna(( 的一个常见问题是它返回一个副本,除非您使用 inplace=True(如上面的链接线程(,但我没有这样做:我正在覆盖TT_df,除非我误解了某些东西。你可以看到 LotFrontage 功能实际上确实从第二个表中消失了,这意味着 fillna((确实对它有用。那么为什么它对其他人不起作用呢?
我怀疑是罪魁祸首,虽然我不知道为什么,但 Na 实际上并不意味着这些功能的 Na:如果我查看数据描述文件,它说:
车库饰面:车库的内部饰面
Fin Finished RFn Rough Finished Unf Unfinished NA No Garage
好的,没关系。但感觉这些 NA 值要么算作 isnull(( 和 fillna(( 的 Na,要么不算在任何一个。为什么它似乎由 isnull(( 而不是 fillna(( 计算?
问题出在以下行上:
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())