2017-01-06 8 views
2

Я создал функцию, которая заменяет NaN в кадре данных Pandas средствами соответствующих столбцов. Я протестировал функцию с небольшим фреймворком данных, и он сработал. Когда я применил его, хотя в гораздо большей dataframe (30000 строк, 9 столбцов) Я получил сообщение об ошибке: IndexError: индекс вне границИндекс за пределами при замене NaN через функцию в Pandas

Функция заключается в следующем:

# 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) 

Небольшой dataframe I используется для проверки функции:

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

Не могли бы вы объяснить ошибку? Ваш совет будет оценен по достоинству.

ответ

3

Причина вы получаете «индекс вне границ», потому что вы присваиваете значение 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
принимает 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) 
+0

Я изменил код в моей функции, как Вы предложили, но я все еще получаю ошибку: IndexError: одно позиционное индексатор вне границ – im7

+0

я побежал, что точный код с образцом 'df', и он бежал. Я получил 'SettingWithCopyWarning', но он запустился. – piRSquared

+0

Да, я это понимаю. Фактически, как я упомянул в своем посте, оригинальная функция еще до исправления запускается в тестовом кадре данных. Однако он не работает на целевом фрейме данных, который можно найти здесь: https://ndownloader.figshare.com/files/2292172 .. Не могли бы вы это объяснить? – im7

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 

 Смежные вопросы

  • Нет связанных вопросов^_^