Jaka jest różnica między NaN i None?

98

Czytam dwie kolumny pliku csv za pomocą pand, readcsv()a następnie przypisuję wartości do słownika. Kolumny zawierają ciągi cyfr i liter. Czasami zdarzają się przypadki, gdy komórka jest pusta. Moim zdaniem wartość odczytywana dla tego hasła w słowniku powinna być, Noneale zamiast tego nanjest przypisywana. Z pewnością Nonejest bardziej opisowy dla pustej komórki, ponieważ ma wartość null, podczas gdy nanpo prostu mówi, że odczytana wartość nie jest liczbą.

Czy moje rozumienie jest prawidłowe, jaka JEST różnica między Nonei nan? Dlaczego jest nanprzypisany zamiast None?

Ponadto, mój słownik sprawdzania pustych komórek używał numpy.isnan():

for k, v in my_dict.iteritems():
    if np.isnan(v):

Ale to daje mi błąd mówiąc, że nie mogę użyć tego czeku v. Wydaje mi się, że dzieje się tak dlatego, że ma być używana zmienna całkowita lub zmiennoprzecinkowa, a nie ciąg. Jeśli to prawda, jak mogę sprawdzić, czy nie vma „pustej komórki” / nanprzypadku?

user1083734
źródło
Tekst qwertynie jest liczbą.
Robert Harvey,
1
@RobertHarvey Wiem, więc na pewno Nonebyłby lepszy opis wartości pustej komórki.
user1083734

Odpowiedzi:

110

NaN jest używany jako symbol zastępczy dla brakujących danych konsekwentnie w pandach , spójność jest dobra. Zwykle czytam / tłumaczę NaN jako „brakujący” . Zobacz także sekcję „Praca z brakującymi danymi” w dokumentacji.

Wes pisze w dokumencie „Wybór reprezentacji NA” :

Po latach używania [NaN] okazało się, przynajmniej moim zdaniem, najlepszą decyzją, biorąc pod uwagę ogólny stan rzeczy w NumPy i Pythonie. Szczególna wartość NaN (Not-A-Number) jest stosowany wszędzie jako wartość NA, i istnieją funkcje API isnulli notnullktóre mogą być wykorzystywane w poprzek dtypes wykryć wartości nA.
...
W związku z tym wybrałem podejście Pythonic „praktyczność przewyższa czystość” i wymieniłem zdolność NA liczb całkowitych, aby uzyskać znacznie prostsze podejście polegające na użyciu specjalnej wartości w tablicach zmiennoprzecinkowych i obiektowych do oznaczania NA oraz promowaniu tablic całkowitych na zmienne, gdy NA muszą być wprowadzone.

Uwaga: „gotcha”, że seria liczb całkowitych zawierająca brakujące dane jest przesyłana do postaci zmiennoprzecinkowej .

Moim zdaniem głównym powodem używania NaN (zamiast None) jest to, że można go przechowywać z typem numpy float64, a nie mniej wydajnym typem obiektu, patrz promocje typu NA .

#  without forcing dtype it changes None to NaN!
s_bad = pd.Series([1, None], dtype=object)
s_good = pd.Series([1, np.nan])

In [13]: s_bad.dtype
Out[13]: dtype('O')

In [14]: s_good.dtype
Out[14]: dtype('float64')

Jeff komentuje to (poniżej):

np.nanpozwala na operacje wektoryzowane; jego wartość zmiennoprzecinkowa, podczas gdy Nonez definicji wymusza typ obiektu, co w zasadzie wyłącza całą wydajność w numpy.

Więc powtórz szybko 3 razy: object == bad, float == good

Mówiąc to, wiele operacji może nadal działać równie dobrze z None i NaN (ale być może nie są obsługiwane, tj. Czasami mogą dawać zaskakujące wyniki ):

In [15]: s_bad.sum()
Out[15]: 1

In [16]: s_good.sum()
Out[16]: 1.0

Aby odpowiedzieć na drugie pytanie:
należy używać pd.isnulli pd.notnullsprawdzać brakujące dane (NaN).

Andy Hayden
źródło
19
dodanie tutaj 2c .... np.nanpozwala na operacje wektoryzowane; to wartość zmiennoprzecinkowa, podczas gdy Nonez definicji wymusza objecttyp i zasadniczo wyłącza całą wydajność w numpy, więc powtórz 3 razy szybko:object==bad, float==good
Jeff
1
Jest <NA>również np.nan?
Gathide
18

NaNmoże być używany jako wartość liczbowa w operacjach matematycznych, podczas gdy Nonenie może (a przynajmniej nie powinien).

NaNjest wartością liczbową zdefiniowaną w standardzie zmiennoprzecinkowym IEEE 754 . Nonejest wewnętrznym typem Pythona ( NoneType) i w tym kontekście bardziej przypomina „nieistniejący” lub „pusty” niż „niepoprawny numerycznie”.

Głównym "symptomem" tego jest to, że jeśli wykonasz, powiedzmy, średnią lub sumę na tablicy zawierającej NaN, nawet pojedynczej, otrzymasz w rezultacie NaN ...

Z drugiej strony nie można wykonywać operacji matematycznych, używając Nonejako operandu.

Tak więc, w zależności od przypadku, możesz użyć Nonejako sposobu, aby powiedzieć algorytmowi, aby nie uwzględniał nieprawidłowych lub nieistniejących wartości w obliczeniach. Oznaczałoby to, że algorytm powinien przetestować każdą wartość, aby sprawdzić, czy tak jest None.

Numpy ma kilka funkcji, aby uniknąć wartości NaN skazić swoje wyniki, jak nansumi nan_to_numnp.

heltonbiker
źródło
Zgadzam się z tobą, że None powinno być używane dla nieistniejących wpisów, więc dlaczego df=pd.readcsv('file.csv')podaje mi NaNwartości dla pustych komórek, a nie None? O ile mi wiadomo, pd.DataFrames nie są wyłączne dla liczb.
user1083734
Cóż, to prawdopodobnie wybór projektu. Przypuszczam, że ramki DataFrames i Series mają a dtype, więc nieprawidłowe wartości dtype=floatmuszą być reprezentowane przez wartości liczbowe, które NaNsą i Nonenie są ( Nonesą z NoneType).
heltonbiker
Ponadto wiele metod Pandas ma naargument, który pozwala zdecydować, której wartości użyjesz do zastąpienia niedostępnych wartości
heltonbiker
Ok dzięki. Więc tak naprawdę nie czytam liczb w mojej ramce DataFrame, ale ciągi cyfr i liter. Jakiego rodzaju kontroli powinienem użyć, aby wykryć puste komórki? Czek jak; jeśli dtype == float: ??
user1083734
Być może pomogłoby wysłanie próbki danych CSV. Mogę sobie wyobrazić, że jeśli istnieją łańcuchy, to dtype będzie ciągiem dla całej kolumny (Series). Ale być może jeśli nie każdy wiersz ma taką samą liczbę kolumn, otrzymasz niedostępne dane. Myślę, że będziesz musiał to sprawdzić.
heltonbiker
3

Funkcja isnan()sprawdza, czy coś jest „nie liczbą” i zwróci, czy zmienna jest liczbą, na przykład isnan(2)zwróci fałsz

Warunek myVar is not Nonezwraca, czy zmienna jest zdefiniowana, czy nie

Twoja tablica numpy używa, isnan()ponieważ ma być tablicą liczb i inicjalizuje wszystkie elementy tablicy, aby NaNte elementy były uważane za "puste"

Stephan
źródło
1
Myślę, isnan(2)że wrócę False, ponieważ 2 nie jest NaN.
heltonbiker
Ponadto numpy.emptynie inicjalizuje wartości tablic do NaN. Po prostu w ogóle nie inicjalizuje wartości.
heltonbiker
5
Właściwa kontrola None- myVar is not Nonenie jest myVar != None.
Jaime,
3
Zauważ, że np.isnan()nie jest zaimplementowane dla zmiennych łańcuchowych, więc jeśli przekażesz mu łańcuch, nastąpi awaria. Lepiej użyć, pd.isnullktóry działa ze stringami.
Michael
-1

Poniżej przedstawiamy różnice:

  • nan należy do klasy float
  • None należy do klasy NoneType

Poniższy artykuł uważam za bardzo pomocny: https://medium.com/analytics-vidhya/dealing-with-missing-values-nan-and-none-in-python-6fc9b8fb4f31

eswara amirthan s
źródło
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie. - Z recenzji
A. Kootstra
@ A.Kootstra Rozumiem
eswara amirthan s
-3

NaNoznacza NIE numer .
Nonemoże oznaczać jakiekolwiek .

diegoaguilar
źródło