使用每列的众数填充多列的Pandas Fillna

10

在处理人口普查数据时,我希望用这两列 ("workclass" 和 "native-country") 的众数来替换其中的 NaN 值。我可以轻松地获取这两列的众数:

mode = df.filter(["workclass", "native-country"]).mode()

返回一个数据框:

  workclass native-country
0   Private  United-States

然而,

df.filter(["workclass", "native-country"]).fillna(mode)

它并不会用对应列的众数替换每一列中的NaN值。有没有比较顺畅的方法可以解决这个问题?

5个回答

16
如果你想用某些列中的众数来填补数据框df中的缺失值,你只需要通过选择位置创建一个Series,并使用fillna函数和iloc方法即可实现。请参考:fillnailoc
cols = ["workclass", "native-country"]
df[cols]=df[cols].fillna(df.mode().iloc[0])
或者:
df[cols]=df[cols].fillna(mode.iloc[0])
您的解决方案:
df[cols]=df.filter(cols).fillna(mode.iloc[0])

示例:

df = pd.DataFrame({'workclass':['Private','Private',np.nan, 'another', np.nan],
                   'native-country':['United-States',np.nan,'Canada',np.nan,'United-States'],
                   'col':[2,3,7,8,9]})

print (df)
   col native-country workclass
0    2  United-States   Private
1    3            NaN   Private
2    7         Canada       NaN
3    8            NaN   another
4    9  United-States       NaN

mode = df.filter(["workclass", "native-country"]).mode()
print (mode)
  workclass native-country
0   Private  United-States

cols = ["workclass", "native-country"]
df[cols]=df[cols].fillna(df.mode().iloc[0])
print (df)
   col native-country workclass
0    2  United-States   Private
1    3  United-States   Private
2    7         Canada   Private
3    8  United-States   another
4    9  United-States   Private

4
你可以像这样做:

您可以采用此方法:

df[["workclass", "native-country"]]=df[["workclass", "native-country"]].fillna(value=mode.iloc[0])

例如,
    import pandas as pd
d={
    'key3': [1,4,4,4,5],
    'key2': [6,6,4],
    'key1': [6,4,4],
}

df=pd.DataFrame.from_dict(d,orient='index').transpose()

那么 df 就是

  key3  key2    key1
0   1   6       6
1   4   6       4
2   4   4       4
3   4   NaN     NaN
4   5   NaN     NaN

然后通过执行以下操作:
l=df.filter(["key1", "key2"]).mode()
df[["key1", "key2"]]=df[["key1", "key2"]].fillna(value=l.iloc[0])

我们知道df是什么,
  key3  key2    key1
0   1   6        6
1   4   6        4
2   4   4        4
3   4   6        4
4   5   6        4

当我这样做时,会得到以下信息:/anaconda3/envs/exts-ml/lib/python3.6/site-packages/pandas/core/frame.py:4024: SettingWithCopyWarning: 尝试在DataFrame的切片副本上设置值 - Mactilda

0

我认为使用字典作为fillna参数“value”是最干净的方法。

参考:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html

从@miriam-farber的回复中创建一个玩具df

import pandas as pd
d={
    'key3': [1,4,4,4,5],
    'key2': [6,6,4],
    'key1': [6,4,4],
}

d_df=pd.DataFrame.from_dict(d,orient='index').transpose()

创建一个字典。
mode_dict = d_df.loc[:,['key2','key1']].mode().to_dict('records')[0]

在fillna方法中使用此字典

d_df.fillna(mode_dict, inplace=True)

0

您也可以使用SimpleImputer来解决这个问题,具体操作如下:

from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='most_frequent', missing_values=np.nan)
df[["workclass", "native-country"]] = imputer.fit_transform(df[["workclass", "native-country"]])

0

这段代码将平均值赋给整数列,将众数赋给对象列,并创建一个包含两种类型列的列表,根据条件填充缺失值。

cateogry_columns=df.select_dtypes(include=['object']).columns.tolist()
integer_columns=df.select_dtypes(include=['int64','float64']).columns.tolist()

for column in df:
    if df[column].isnull().any():
        if(column in cateogry_columns):
            df[column]=df[column].fillna(df[column].mode()[0])
        else:
            df[column]=df[column].fillna(df[column].mean)`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接