Come posso sostituire tutti i valori NaN con Zeri in una colonna di un frame di dati Panda


458

Ho un frame di dati come di seguito

      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

quando provo ad applicare una funzione alla colonna Quantità ottengo il seguente errore.

ValueError: cannot convert float NaN to integer

Ho provato ad applicare una funzione usando .isnan dal Math Module Ho provato l'attributo panda .replace Ho provato l'attributo .sparse data dai panda 0.9 Ho anche provato se NaN == NaN in una funzione. Ho anche visto questo articolo Come posso sostituire i valori NA con zeri in un frame di dati R? mentre guardo alcuni altri articoli. Tutti i metodi che ho provato non hanno funzionato o non riconoscono NaN. Eventuali suggerimenti o soluzioni sarebbero apprezzati.


L'unico problema è che df.fill.na () non funziona se il frame di dati su cui lo stai applicando viene ricampionato o se è stato suddiviso tramite la funzione loc
Prince Agarwal,

Risposte:


754

Credo che DataFrame.fillna()lo farà per te.

Link a Documenti per un frame di dati e per una serie .

Esempio:

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

Per riempire i NaN in una sola colonna, selezionare solo quella colonna. in questo caso sto usando inplace = True per cambiare effettivamente il contenuto di 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

MODIFICARE:

Per evitare un SettingWithCopyWarning, utilizzare la funzionalità specifica specifica per colonna:

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

1
È garantito che df[1]sia una vista piuttosto che una copia del DF originale? Ovviamente, se c'è una rara situazione in cui è una copia, causerebbe un bug super problematico. C'è una chiara dichiarazione al riguardo nella documentazione di Panda?
massimo

@max Vedi questo, potrebbe rispondere alla tua domanda: stackoverflow.com/questions/23296282/…
Aman

Grazie. È corretto intendere che in quella risposta un "indicizzatore che imposta" è l'operazione di indicizzazione più esterna (eseguita appena prima dell'assegnazione. Pertanto, qualsiasi assegnazione che utilizza solo un singolo indicizzatore è garantita, rendendo il tuo codice sicuro?
max


1
l'ultimo esempio lancia un SettingWithCopyWarning
Sip

124

Non è garantito che il taglio restituisca una vista o una copia. Tu puoi fare

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

14
Ho appena scoperto il problema "inplace = True". Questa risposta evita il problema e penso che sia la soluzione più pulita presentata.
TimCera,

48

È possibile utilizzare replaceper passare NaNa 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)

Sostituirà solo NaN? o sostituirà anche il valore dove NAo NaNcome df.fillna(0)? Sto cercando una soluzione che sostituisca il valore solo dove c'è NaNe nonNA
Shyam Bhimani

1
@ShyamBhimani dovrebbe sostituire solo i NaNvalori dove np.isnanè True
Anton Protopopov

23

Volevo solo fornire un po 'di aggiornamento / caso speciale poiché sembra che le persone vengano ancora qui. Se si utilizza un indice multiplo o in altro modo un indice-slicer, l'opzione inplace = True potrebbe non essere sufficiente per aggiornare la sezione prescelta. Ad esempio in un multiindice di livello 2x2 questo non cambierà alcun valore (a partire da panda 0.15):

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

Il "problema" è che il concatenamento interrompe la capacità di fillna di aggiornare il frame di dati originale. Metto il "problema" tra virgolette perché ci sono buoni motivi per le decisioni di progettazione che hanno portato a non interpretare attraverso queste catene in determinate situazioni. Inoltre, questo è un esempio complesso (anche se mi sono davvero imbattuto in esso), ma lo stesso può applicarsi a un minor numero di indici a seconda di come si suddivide.

La soluzione è DataFrame.update:

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

È una riga, legge ragionevolmente bene (una sorta di) ed elimina qualsiasi pasticcio inutile con variabili o loop intermedi, consentendo al contempo di applicare fillna a qualsiasi slice multilivello che ti piace!

Se qualcuno riesce a trovare posti che non funzionano, si prega di postare nei commenti, ho fatto un casino con esso e guardando la fonte e sembra risolvere almeno i miei problemi di fetta multi-indice.


21

Il codice seguente ha funzionato per me.

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

7

Modo semplice per riempire i valori mancanti: -

riempimento delle colonne di stringa: quando le colonne di stringa hanno valori mancanti e valori NaN.

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

riempimento di colonne numeriche: quando le colonne numeriche hanno valori mancanti e valori NaN.

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

riempiendo NaN di zero:

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

5

Puoi anche usare i dizionari per riempire i valori NaN delle colonne specifiche nel DataFrame piuttosto che riempire tutto il DF con qualche 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)

Questa è la soluzione pensata dallo sviluppatore per la domanda del PO.
johnDanger,

4

inserisci qui la descrizione dell'immagine

Considerando la colonna particolare Amountnella tabella sopra è di tipo intero. Quanto segue sarebbe una soluzione:

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

Allo stesso modo, puoi riempirlo con vari tipi di dati come float,str e così via.

In particolare, prenderei in considerazione il tipo di dati per confrontare vari valori della stessa colonna.


2

Per sostituire i valori na nei panda

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

se inplace = Falseinvece di aggiornare df (dataframe) restituirà i valori modificati.


1

Se dovessi convertirlo in un frame di dati Panda, puoi anche farlo utilizzando fillna.

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

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

Ciò restituirà quanto segue:

     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

Ci sono due opzioni disponibili principalmente; in caso di imputazione o riempimento di valori mancanti NaN / np.nan con solo sostituzioni numeriche (tra le colonne:

df['Amount'].fillna(value=None, method= ,axis=1,) è sufficiente:

Dalla documentazione:

valore: scalare, dict, Series o DataFrame Valore da utilizzare per riempire i buchi (ad es. 0), in alternativa un dict / Series / DataFrame di valori che specifica quale valore utilizzare per ciascun indice (per una serie) o colonna (per un DataFrame) . (i valori non inclusi in dict / Series / DataFrame non verranno riempiti). Questo valore non può essere un elenco.

Ciò significa che non è più possibile imputare "stringhe" o "costanti".

Per imputazioni più specializzate utilizzare 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

Per sostituire nan in colonne diverse con modi diversi:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.