Як я можу замінити всі значення NaN на нулі у стовпчику фрейму даних панди


457

У мене є кадр даних, як показано нижче

      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

Коли я намагаюся застосувати функцію до стовпця "Сума", я отримую таку помилку.

ValueError: cannot convert float NaN to integer

Я спробував застосувати функцію, використовуючи .isnan з модуля Math. Я спробував атрибут pandas .replace, я спробував атрибут .sparse даних з панд 0,9, я також спробував, якщо NaN == NaN-оператор у функції. Я також переглянув цю статтю Як замінити значення NA нулями в рамці даних R? переглядаючи деякі інші статті. Усі методи, які я спробував, не спрацювали або не розпізнають NaN. Будь-які підказки чи рішення будуть вдячні.


Єдина проблема - df.fill.na () не працює, якщо кадр даних, до якого ви його застосовуєте, перекомпонований або був перерізаний через локальну функцію
Принц Агарвал

Відповіді:


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

Щоб заповнити NaNs лише в одному стовпчику, виберіть саме цей стовпець. в цьому випадку я використовую 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
DisplayName

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
Shyam Bhimani

1
@ShyamBhimani він повинен замінити лише ті NaNзначення, де np.isnanTrue
Антон Протопопов

23

Я просто хотів надати трохи оновлення / особливого випадку, оскільки, схоже, люди все ще приїжджають сюди. Якщо ви використовуєте мультиіндексний або іншим чином використовуєте індекс-розрізник, опції inplace = True може бути недостатньо для оновлення вибраного фрагмента. Наприклад, у мультиіндексі рівня 2х2 це не змінить жодних значень (станом на панди 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))

Це один рядок, читається досить добре (на зразок) і виключає зайве возитися з проміжними змінними або петлями, дозволяючи застосувати філну до будь-якого багаторівневого фрагмента, який вам подобається!

Якщо хтось може знайти місця, на яких це не працює, опублікуйте в коментарях, я псувався з ним і дивлюсь на джерело, і, здається, вирішує хоча б мої проблеми з багатоіндексним фрагментом.



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 деяким oneValue.

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)

Це вирішення питання щодо ОП щодо розробки розробника.
johnDanger

4

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

Враховуючи, що конкретний стовпчик Amountу наведеній таблиці є цілим типом. Вирішення може бути наступним:

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

Крім того , ви можете заповнити його з різними типами даних , наприклад float, strі так далі.

Зокрема, я б розглядав тип даних для порівняння різних значень одного стовпця.


2

Для заміни значень na в пандах

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

якщо inplace = Falseзамість оновлення df (фрейму даних) він поверне змінені значення.


1

Якщо ви повинні перетворити його в рамку даних панди, ви також можете це досягти, використовуючи 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,) достатньо:

З документації:

значення: скалярне, dict, серія або значення DataFrame, яке потрібно використовувати для заповнення отворів (наприклад, 0), поперемінно dict / Series / DataFrame значень, що визначають, яке значення використовувати для кожного індексу (для серії) або стовпця (для 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

Щоб замінити нан у різних стовпцях різними способами:

   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.