通过Pandas中的函数替换NaN时索引超出范围

时间:2017-01-06 00:06:50

标签: python function pandas indexoutofboundsexception nan

我创建了一个函数,用相应列的方法替换Pandas数据帧中的NaN。我用一个小的数据帧测试了这个函数并且它工作正常。当我将它应用到更大的数据帧(30,000行,9列)时,我收到错误消息:IndexError:index out of bounds

该功能如下:

# The 'update' function will replace all the NaNs in a dataframe with the mean of the respective columns

def update(df):   # the function takes one argument, the dataframe that will be updated
      ncol = df.shape[1]  # number of columns in the dataframe
      for i in range(0 , ncol):  # loops over all the columns
             df.iloc[:,i][df.isnull().iloc[:, i]]=df.mean()[i]  # subsets the df using the isnull() method, extracting the positions
                                                        # in each column where the 
      return(df)

我用来测试该功能的小数据帧如下:

     0   1   2  3
0   NaN NaN  3  4
1   NaN NaN  7  8
2   9.0 10.0 11 12

你能解释一下这个错误吗?您的建议将不胜感激。

2 个答案:

答案 0 :(得分:4)

我会将DataFrame.fillna()方法与DataFrame.mean()方法结合使用:

In [130]: df.fillna(df.mean())
Out[130]:
     0     1   2   3
0  9.0  10.0   3   4
1  9.0  10.0   7   8
2  9.0  10.0  11  12

平均值:

In [138]: df.mean()
Out[138]:
0     9.0
1    10.0
2     7.0
3     8.0
dtype: float64

答案 1 :(得分:3)

您获得“索引越界”的原因是因为当df.mean()[i]是应该是序数位置的一次迭代时,您正在分配值idf.mean()Series,其索引是df的列。 df.mean()[something]表示something最好是列名。但它们不是,这就是你得到错误的原因。

您的代码...已修复

def update(df):   # the function takes one argument, the dataframe that will be updated
      ncol = df.shape[1]  # number of columns in the dataframe
      for i in range(0 , ncol):  # loops over all the columns
             df.iloc[:,i][df.isnull().iloc[:, i]]=df.mean().iloc[i]  # subsets the df using the isnull() method, extracting the positions
                                                        # in each column where the 
      return(df)

此外,您的功能是直接更改df。你可能要小心。我不确定那是你的意图。

所有这一切。我建议采用另一种方法

def update(df):
    return df.where(df.notnull(), df.mean(), axis=1)

您可以使用任意数量的方法来填充缺失的均值。我建议使用@ MaxU的答案。

<强> df.where
当第一个arg为df时,取True,否则为第二个参数

df.where(df.notnull(), df.mean(), axis=1)

df.combine_first尴尬pandas广播

df.combine_first(pd.DataFrame([df.mean()], df.index))

np.where

pd.DataFrame(
    np.where(
        df.notnull(), df.values,
        np.nanmean(df.values, 0, keepdims=1)),
    df.index, df.columns)