Как я могу заменить все значения NaN на нули в столбце кадра данных pandas?


458

У меня есть датафрейм, как показано ниже

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

Когда я пытаюсь применить функцию к столбцу Amount, я получаю следующую ошибку.

ValueError: cannot convert float NaN to integer

Я попытался применить функцию с помощью .isnan из математического модуля. Я попробовал атрибут .replace pandas. Я попробовал атрибут .sparse data из pandas 0.9. Я также попробовал, если в функции был NaN == оператор NaN. Я также посмотрел эту статью. Как заменить значения NA нулями в кадре данных R? глядя на некоторые другие статьи. Все методы, которые я пробовал, не работали или не распознают NaN. Любые советы или решения будут оценены.


Единственная проблема в том, что df.fill.na () не работает, если фрейм данных, к которому вы применяете его, передискретизирован или разрезан с помощью функции loc
Prince Agarwal

Ответы:


754

Я верю, DataFrame.fillna()что сделаю это для вас.

Ссылка на Документы для блока данных и для Серии .

Пример:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

Чтобы заполнить NaN только в одном столбце, выберите только этот столбец. в этом случае я использую inplace = True, чтобы фактически изменить содержимое df.

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

РЕДАКТИРОВАТЬ:

Чтобы избежать SettingWithCopyWarning, используйте встроенную функцию, специфичную для столбцов:

df.fillna({1:0}, inplace=True)

1
Гарантируется ли, что df[1]это представление, а не копия оригинального DF? Очевидно, что если есть редкая ситуация, когда это копия, это может вызвать очень неприятную ошибку. Есть ли четкое утверждение об этом в документации панд?
максимум

@max См. это, возможно, ответит на ваш вопрос: stackoverflow.com/questions/23296282/…
Аман

Спасибо. Верно ли мое понимание того, что в этом ответе «индексатор, который устанавливает» является самой внешней операцией индексации (выполняемой непосредственно перед назначением. Поэтому любое назначение, в котором используется только один индексатор, гарантированно будет безопасным, что сделает ваш код безопасным?
максимум

1
Почему это не работает для меня? см .: stackoverflow.com/questions/39452095/how-to-fillna-with-value-0
отображаемое имя

1
последний пример бросает SettingWithCopyWarning
Sip

124

Не гарантируется, что нарезка возвращает представление или копию. Ты можешь сделать

df['column'] = df['column'].fillna(value)

14
Только что обнаружил проблему "inplace = True". Этот ответ позволяет избежать проблемы, и я думаю, что это самое чистое решение из представленных.
TimCera

48

Вы можете использовать replaceдля изменения NaNна 0:

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

Это только заменит NaN? или это также заменит значение где NAили NaNкак df.fillna(0)? Я ищу решение, которое заменяет только ценность там, где есть, NaNа неNA
Шьям Бхимани

1
@ShyamBhimani это должно заменить только NaNто есть значения где np.isnanTrue
Антон Протопопов

23

Я просто хотел представить немного обновления / особого случая, так как похоже, что люди все еще приходят сюда. Если вы используете мультииндекс или иным образом индекс-слайсер, опции inplace = True может быть недостаточно для обновления выбранного слайса. Например, в мультииндексе уровня 2x2 это не изменит никаких значений (для панд 0,15):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

«Проблема» в том, что объединение в цепочку нарушает возможность обновления исходного кадра данных. Я поставил «проблему» в кавычки, потому что есть веские причины для дизайнерских решений, которые привели к тому, что в определенных ситуациях не интерпретируются через эти цепочки. Кроме того, это сложный пример (хотя я действительно столкнулся с ним), но то же самое может относиться к меньшему количеству уровней индексов в зависимости от того, как вы разрезаете.

Решением является DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

Это одна строка, которая читается достаточно хорошо (вроде) и устраняет все ненужные путаницы с промежуточными переменными или циклами, позволяя вам применять fillna к любому многоуровневому слайсу, который вам нравится!

Если кто-то может найти места, где это не работает, пожалуйста, напишите в комментариях, я возился с этим и смотрю на источник, и это, кажется, решает, по крайней мере, мои проблемы с многоиндексными срезами.



7

Простой способ заполнить пропущенные значения: -

заполнение строковых столбцов: когда в строковых столбцах отсутствуют значения и значения NaN.

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

заполнение числовых столбцов: когда числовые столбцы имеют пропущенные значения и значения NaN.

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

заполнение NaN с нуля:

df['column name'].fillna(0, inplace = True)

5

Вы также можете использовать словари для заполнения значений NaN определенных столбцов в DataFrame, а не для заполнения всех DF одним значением.

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

Это предназначенное разработчиком решение вопроса ОП.
ДжонДанджер

4

введите описание изображения здесь

Учитывая, что конкретный столбец Amountв приведенной выше таблице имеет целочисленный тип. Следующее будет решением:

df['Amount'] = df.Amount.fillna(0).astype(int)

Точно так же вы можете заполнить его различными типами данных, например float, strи так далее.

В частности, я хотел бы рассмотреть тип данных для сравнения различных значений одного и того же столбца.


2

Заменить значения в пандах

df['column_name'].fillna(value_to_be_replaced,inplace=True)

если inplace = Falseвместо обновления df (dataframe) он вернет измененные значения.


1

Если вы должны были преобразовать его в фрейм данных Pandas, вы также можете сделать это с помощью fillna.

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

Это вернет следующее:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

1

Есть два варианта, доступных в первую очередь; в случае вменения или заполнения пропущенных значений NaN / np.nan только числовыми заменами (по столбцу (столбцам)):

df['Amount'].fillna(value=None, method= ,axis=1,) достаточно:

Из документации:

value: скаляр, dict, Series или DataFrame Значение, используемое для заполнения отверстий (например, 0), поочередно dict / Series / DataFrame значений, указывающих, какое значение использовать для каждого индекса (для Series) или столбца (для DataFrame) , (значения, не указанные в dict / Series / DataFrame, заполняться не будут). Это значение не может быть списком.

Это означает, что «строки» или «константы» больше не могут быть вменены.

Для более специализированных расчетов используйте SimpleImputer () :

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])

0

Чтобы заменить nan в разных столбцах разными способами:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.