【问题标题】:Index out of bounds when replacing NaNs through a function in Pandas通过 Pandas 中的函数替换 NaN 时索引超出范围
【发布时间】:2017-05-20 16:41:31
【问题描述】:

我创建了一个函数,该函数将 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

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

【问题讨论】:

    标签: python function pandas indexoutofboundsexception nan


    【解决方案1】:

    我会将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
    

    【讨论】:

      【解决方案2】:

      您得到“索引超出范围”的原因是因为您在分配值 df.mean()[i]i 是应该是序数位置的一次迭代。 df.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
      当第一个参数是 True 时采用 df 否则是第二个参数

      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)
      

      【讨论】:

      • 我按照您的建议更改了函数中的代码,但仍然出现错误:IndexError: single positional indexer is out-of-bounds
      • 我用示例 df 运行了那个确切的代码,它运行了。我得到了SettingWithCopyWarning,但它运行了。
      • 是的,我明白这一点。事实上,正如我在帖子中提到的,甚至在测试数据帧中的校正运行之前,原始函数也是如此。但是,它在目标数据帧上失败了,可以在这里找到:ndownloader.figshare.com/files/2292172.. 你能解释一下吗?
      猜你喜欢
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 2021-11-29
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      相关资源
      最近更新 更多