熊猫填写np.nan问题

时间:2016-04-28 21:48:52

标签: python windows pandas

环境

  • Windows 8.1
  • python 3.5
  • 熊猫

我想做什么

根据以下规则填充np.nan列中的pandas.DataFrame

  1. 如果值为数字,请使用其余值的平均值填充np.nan
  2. 如果值不是数字,请使用其余值的模式填充np.nan
  3. 问题

    以下代码似乎无效。

    # build DataFrame
    dfna = pd.DataFrame(np.random.randn(100,5), columns=list('ABCDE'))
    dfna['F'] = [random.choice(list('abcdefghijkf')) for i in range(100)]
    dfna[::20] = np.nan
    
    # filling np.nan
    def filler(x):
        if type(x) == 'numeric':
            x.fillna(x.mean())
        else:
            x.fillna(x.mode())
    
    dfna.apply(filler)
    

    我知道为什么会失败。这是因为type(x)返回'pandas.core.series.Series'。但是,我如何实现目标?任何帮助,将不胜感激。感谢。

    solutions(2016/4/29)

    解决方法1

    numeric_cols = dfna._get_numeric_data().columns.tolist()
    nonnumeric_cols = [c for c in dfna if c not in numeric_cols]
    
    dfna_num = dfna.loc[:, numeric_cols] = \
        dfna[numeric_cols].apply(lambda col: col.fillna(col.mean()))
    
    dfna_nonnum = dfna.loc[:, nonnumeric_cols] = \
        dfna[nonnumeric_cols].apply(lambda col: col.fillna(col.value_counts()[0]))
    
    pd.concat([dfna_num, dfna_nonnum], axis=1)
    

    溶液2

    for col in dfna.columns:
        if dfna[col].dtype != 'object':
            dfna[col].fillna(dfna[col].mean(),inplace=True)
        else:
            dfna[col].fillna(dfna[col].mode(), inplace=True)
    

    谢谢,伙计们!

2 个答案:

答案 0 :(得分:2)

首先将数字和非数字列分开。

numeric_cols = dfna._get_numeric_data().columns.tolist()
nonnumeric_cols = [c for c in dfna if c not in numeric_cols]

然后将平均值分配给数字值,并使用value_counts来获取最常出现的项目(如果存在平局,则使用第一个项目。)

dfna.loc[:, numeric_cols] = \
    dfna[numeric_cols].apply(lambda col: col.fillna(col.mean()))

dfna.loc[:, nonnumeric_cols] = \
    dfna[nonnumeric_cols].apply(lambda col: col.fillna(col.value_counts().head(1).index[0]))

或者您可以使用此功能:

def filler(series):
    avg = series._get_numeric_data().mean()
    series.fillna(series.mode().values[0] if np.isnan(avg) else avg, inplace=True)

dfna.apply(filler)

答案 1 :(得分:0)

我头脑中的东西:

for col in dfna.columns:
    if dfna[col].dtype != 'object':
        dfna[col].fillna(dfna[col].mean(),inplace=True)
    else:
        dfna[col].fillna(dfna[col].mode(), inplace=True)

inplace=True直接在框架内编辑(无副本)。

但请注意,如果non-numeric列中没有共同元素,则mode会返回[],因此原始值保持不变。