Skip to content

NumPy: Sostituire NaN (np.nan) in ndarray

Python

In NumPy, per sostituire i valori mancanti NaN (np.nan) in ndarray con altri numeri, utilizzare np.nan_to_num() o np.isnan().

In questo articolo vengono descritti i seguenti contenuti.

  • Valore mancante NaN (np.nan) in NumPy
  • Specifica l’argomento fill_values ​​di np.genfromtxt()
  • Sostituisci NaN con np.nan_to_num()
  • Sostituisci NaN con np.isnan()

Se si desidera eliminare la riga o la colonna contenente il valore mancante invece di sostituirlo, vedere il seguente articolo.

Valore mancante NaN (np.nan) in NumPy

Quando leggi un file CSV con np.genfromtxt(), per essere considerato predefinito, i dati mancanti vengono come un valore mancante NaN (non un numero).

Durante l’output con print(), viene stampato come nan.

import numpy as np

a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(a)
# [[11. 12. nan 14.]
#  [21. nan nan 24.]
#  [31. 32. 33. 34.]]

Se vuoi generare NaN in modo esplicito, usa np.nan o float(‘nan’). Puoi anche importare il modulo matematico della libreria standard e usare math.nan. Sono tutti uguali.

a_nan = np.array([0, 1, np.nan, float('nan')])
print(a_nan)
# [ 0.  1. nan nan]

Poiché il confronto dei valori mancanti con == risulta False, utilizzare np.isnan() o math.isnan() per verificare se il valore è NaN o meno.

print(np.nan == np.nan)
# False

print(np.isnan(np.nan))
# True

np.isnan() controlla se ogni elemento di ndarray è un NaN o meno.

print(a_nan == np.nan)
# [False False False False]

print(np.isnan(a_nan))
# [False False  True  True]

Specifica l’argomento fill_values ​​di np.genfromtxt()

Se mancano i dati di un file CSV, puoi compilare la parte mancante con qualsiasi valore specificando l’argomento fill_values ​​durante la lettura con np.genfromtxt().

Ad esempio, se vuoi compilare NaN con 0:

a_fill = np.genfromtxt('data/src/sample_nan.csv', delimiter=',', filling_values=0)
print(a_fill)
# [[11. 12.  0. 14.]
#  [21.  0.  0. 24.]
#  [31. 32. 33. 34.]]

Sostituisci NaN con np.nan_to_num()

È possibile utilizzare np.nan_to_num() per sostituire NaN.

Nota che np.nan_to_num() sostituisce anche infinity inf. Vedere il seguente articolo per i dettagli.

Se specifichi ndarray come primo argomento di np.nan_to_num(), viene creato un nuovo ndarray con i valori mancanti sostituito con 0 per configurazione predefinita. Il ndarray originale non viene modificato.

a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(np.nan_to_num(a))
# [[11. 12.  0. 14.]
#  [21.  0.  0. 24.]
#  [31. 32. 33. 34.]]

print(a)
# [[11. 12. nan 14.]
#  [21. nan nan 24.]
#  [31. 32. 33. 34.]]

Se il secondo argomento copy è impostato su False, il ndarray originale viene modificato.

print(np.nan_to_num(a, copy=False))
# [[11. 12.  0. 14.]
#  [21.  0.  0. 24.]
#  [31. 32. 33. 34.]]

print(a)
# [[11. 12.  0. 14.]
#  [21.  0.  0. 24.]
#  [31. 32. 33. 34.]]

In NumPy versione 1.17 o successive, il valore da può essere specificato dall’argomento sostituirenan.

a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(np.nan_to_num(a, nan=-1))
# [[11. 12. -1. 14.]
#  [21. -1. -1. 24.]
#  [31. 32. 33. 34.]]

Puoi sostituire NaN con la media degli elementi a cui non mancano i valori con np.nanmean().

print(np.nanmean(a))
# 23.555555555555557

print(np.nan_to_num(a, nan=np.nanmean(a)))
# [[11.         12.         23.55555556 14.        ]
#  [21.         23.55555556 23.55555556 24.        ]
#  [31.         32.         33.         34.        ]]

Nelle versioni in cui l’argomento nan non èto, puoi sostituireN con un valore diverso da 0 nel modo seguente.

Sostituisci NaN con np.isnan()

Puoi usare np.isnan() per verificare se gli elementi di ndarray sono NaN o meno.

a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
print(np.isnan(a))
# [[False False  True False]
#  [False  True  True False]
#  [False False False False]]

Usando questo risultato, puoi assegnare qualsiasi valore all’elemento del valore mancante.

Se vuoi Na sostituireN con 0:

a[np.isnan(a)] = 0
print(a)
# [[11. 12.  0. 14.]
#  [21.  0.  0. 24.]
#  [31. 32. 33. 34.]]

Puoi anche usare np.nanmean() per sostituire NaN con il valore medio.

a = np.genfromtxt('data/src/sample_nan.csv', delimiter=',')
a[np.isnan(a)] = np.nanmean(a)
print(a)
# [[11.         12.         23.55555556 14.        ]
#  [21.         23.55555556 23.55555556 24.        ]
#  [31.         32.         33.         34.        ]]