Python:如何用中位数替换缺失值列

时间:2019-02-26 06:30:51

标签: pandas

我的数据框如下

df = pd.DataFrame({'A': [1, 2, 3], 'B': [1.45, 2.33, np.nan], 'C': [4, 5, 6], 'D': [4.55, 7.36, np.nan]}) 

我想以通用方式替换缺少的值,即np.nan。为此,我创建了如下函数

def treat_mis_value_nu(df):
    df_nu = df.select_dtypes(include=['number'])
    lst_null_col = df_nu.columns[df_nu.isnull().any()].tolist()
        if len(lst_null_col)>0:
            for i in lst_null_col:
                if df_nu[i].isnull().sum()/len(df_nu[i])>0.10:
                    df_final_nu = df_nu.drop([i],axis=1)
                else:
                    df_final_nu = df_nu[i].fillna(df_nu[i].median(),inplace=True)
    return df_final_nu

当我按如下方式应用此功能

df_final = treat_mis_value_nu(df)

我正在获取如下数据框

    A    B  C
 0  1  1.0  4
 1  2  2.0  5
 2  3  NaN  6

因此它实际上已正确删除了列D,但未能删除列B。 我知道,过去曾对此主题(here)进行过讨论。还是我可能会缺少一些东西吗?

2 个答案:

答案 0 :(得分:1)

使用:

df = pd.DataFrame({'A': [1, 2, 3,5,7], 'B': [1.45, 2.33, np.nan, np.nan, np.nan], 
                   'C': [4, 5, 6,8,7], 'D': [4.55, 7.36, np.nan,9,10],
                   'E':list('abcde')}) 
print (df)
   A     B  C      D  E
0  1  1.45  4   4.55  a
1  2  2.33  5   7.36  b
2  3   NaN  6    NaN  c
3  5   NaN  8   9.00  d
4  7   NaN  7  10.00  e

def treat_mis_value_nu(df):
    #get only numeric columns to dataframe
    df_nu = df.select_dtypes(include=['number'])
    #get only columns with NaNs
    df_nu = df_nu.loc[:, df_nu.isnull().any()]
    #get columns for remove with mean instead sum/len, it is same
    cols_to_drop = df_nu.columns[df_nu.isnull().mean() <= 0.30]
    #replace missing values of original columns and remove above thresh    
    return df.fillna(df_nu.median()).drop(cols_to_drop, axis=1)

print (treat_mis_value_nu(df))
   A  C      D  E
0  1  4   4.55  a
1  2  5   7.36  b
2  3  6   8.18  c
3  5  8   9.00  d
4  7  7  10.00  e

答案 1 :(得分:0)

我建议您查看sklearn Imputer transformer。我不认为它可以删除列,但可以用“通用”方式明确地填充它们-例如,用相关列的中位数填充缺失值。

您可以这样使用它:

from sklearn.preprocessing import Imputer

imputer = Imputer(strategy='median')

num_df = df.values
names = df.columns.values

df_final = pd.DataFrame(imputer.transform(num_df), columns=names)

如果您要进行其他转换,可以考虑进行转换Pipeline,甚至可以制作自己的转换器来执行定制任务。