np.nan și funcțiile nan* în NumPy

Lucrul cu valori lipsă: np.nan, np.isnan și funcțiile nansum, nanmean, nanmin, nanmax care ignoră NaN.

Sintaxă
np.nan
np.isnan(x)
np.nansum(a, axis=None)
np.nanmean(a, axis=None)
np.nanmax(a, axis=None)

Ce face np.nan și funcțiile nan*

np.nan („not a number”) marchează o valoare lipsă sau nedefinită într-un tablou de numere cu virgulă. Orice calcul cu nan dă tot nan, deci np.mean() sau np.sum() pe un tablou cu o singură valoare lipsă returnează nan.

np.isnan() returnează o mască booleană cu True unde valoarea este nan. Nu poți folosi == np.nan, pentru că nan nu este egal nici cu el însuși. Funcțiile np.nansum(), np.nanmean(), np.nanmedian(), np.nanstd(), np.nanmin(), np.nanmax() fac același calcul ca variantele fără „nan”, dar sar peste valorile lipsă.

Dacă un rând sau o coloană conține doar nan, np.nanmean() și np.nanmax() returnează nan și emit RuntimeWarning („Mean of empty slice” / „All-NaN slice encountered”). Verifică întâi cu np.isnan(a).all() dacă există măcar o valoare. np.nansum() pe date doar cu nan returnează 0.

Parametri

Parametru Descriere
x / a Tabloul de verificat sau de agregat.
axis Ca la funcțiile obișnuite: None, 0, 1.

Ce returnează

np.isnan: o mască booleană de aceeași formă. Funcțiile nan*: un scalar sau un tablou, calculat fără valorile lipsă.

Exemple

Exemplul 1: mean dă nan, nanmean ignoră valoarea lipsă

Mihai lipsește de la o probă, deci nota lui este np.nan.

import numpy as np

note = np.array([9.5, 7.0, np.nan, 8.5])
print("mean:", np.mean(note))
print("nanmean:", np.nanmean(note))
print("nansum:", np.nansum(note))
print("nanmax:", np.nanmax(note))
print("Lipsesc:", np.isnan(note).sum())

Rezultat

mean: nan
nanmean: 8.333333333333334
nansum: 25.0
nanmax: 9.5
Lipsesc: 1

Exemplul 2: De ce nu merge == np.nan

import numpy as np

a = np.array([1.0, np.nan, 3.0])
print(np.nan == np.nan)
print(a == np.nan)
print(np.isnan(a))
print(a[~np.isnan(a)])

Rezultat

False
[False False False]
[False  True False]
[1. 3.]

Exemplul 3: Coloane cu toate valorile lipsă

Coloana a doua are doar nan. Media se calculează doar pentru coloanele care au cel puțin o valoare, ca să nu apară RuntimeWarning.

import numpy as np

date = np.array([
    [10.0, np.nan, 4.0],
    [np.nan, np.nan, 6.0],
])

are_valori = ~np.isnan(date).all(axis=0)
print(are_valori)

medii = np.full(date.shape[1], np.nan)
medii[are_valori] = np.nanmean(date[:, are_valori], axis=0)
print(medii)

Rezultat

[ True False  True]
[10. nan  5.]

Greșeli frecvente

  • Cauți valorile lipsă cu a == np.nan: rezultatul este mereu False. Folosește np.isnan(a).
  • Pui np.nan într-un tablou de întregi: primești ValueError, pentru că nan există doar pentru tipurile float. Creează tabloul cu dtype=float.
  • Apelezi np.nanmean() pe o coloană doar cu nan și apare RuntimeWarning: Mean of empty slice. Verifică înainte cu np.isnan(...).all().

Comenzi înrudite

  • np.mean(): Calculează media aritmetică (np.mean), mediana (np.median) și media ponderată (np.average cu weights).
  • np.sum(): Adună elementele unui tablou: pe tot tabloul, pe coloane (axis=0) sau pe rânduri (axis=1).
  • Măști booleene: Selectează elementele care îndeplinesc o condiție, cu un tablou de True/False pus între paranteze pătrate.
  • ndarray.dtype: Arată tipul elementelor dintr-un tablou (int64, float64, bool etc.) și câți octeți ocupă fiecare.