2013-07-08 20 views
50

Czytam dwie kolumny pliku csv za pomocą pandy readcsv(), a następnie przypisuję wartości do słownika. Kolumny zawierają ciągi liczb i liter. Czasami zdarzają się przypadki, w których komórka jest pusta. Moim zdaniem, wartość odczytana do tego wpisu słownikowego powinna wynosić None, ale zamiast tego jest przypisana nan. Z pewnością None jest bardziej opisowe dla pustej komórki, ponieważ ma wartość pustą, podczas gdy nan mówi tylko, że odczytana wartość nie jest liczbą.Jaka jest różnica między NaN i None?

Czy moje zrozumienie jest poprawne, jaka jest różnica między None a nan? Dlaczego zamiast przypisano None?

Również mój słownik czek na 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ę korzystać z tej czek na v. Sądzę, że dzieje się tak dlatego, że należy używać zmiennej całkowitej lub zmiennoprzecinkowej, a nie ciąg. Jeśli to prawda, w jaki sposób mogę sprawdzić v dla przypadku "pustej komórki"/nan?

+0

Tekst 'qwerty' nie jest liczbą. –

+1

@RobertHarvey Wiem, że na pewno 'None' będzie lepszym opisem wartości pustej komórki. – user1083734

+0

@ user1083734 moja odpowiedź opisuje, że – Stephan

Odpowiedz

49

NaN jest używany jako symbol zastępczy dla missing data consistently in pandas, konsystencja jest dobra. Zwykle czytam/tłumaczę NaN jako "brakujący". Zobacz także rozdział 'working with missing data' w dokumentacji.

Wes pisze w docs 'choice of NA-representation':

Po latach użytkowania produkcyjnego [NaN] udowodnił, przynajmniej moim zdaniem, być najlepsza decyzja, biorąc pod uwagę stan rzeczy w NumPy i Python w generał. Specjalna wartość NaN (Not-A-Number) jest używana jako wszędzie gdzie jako wartość NA i istnieją funkcje API isnull i notnull, które mogą być używane przez dtypes do wykrywania wartości NA.
...
Tak więc wybrałem Pythoniczne podejście "czystość bitów praktycznych" i wymieniłem całkowitą zdolność NA dla znacznie prostszego podejścia do używania specjalnej wartości w float i macierzach obiektów w celu oznaczenia NA, i promowania tablic całkowitych do floatingu. kiedy należy wprowadzić NA.

Uwaga: "gotcha" that integer Series containing missing data are upcast to floats.

Moim zdaniem głównym powodem korzystania NaN (ponad None) jest to, że może on być przechowywany z NumPy za float64 dtype, a nie mniej skuteczny obiektu dtype, zobaczyć NA type promotions.

# 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 komentarze (poniżej) na ten temat:

np.nan pozwala na operacje vectorized; jest wartością float, podczas gdy None, z definicji, wymusza typ obiektu, który zasadniczo wyłącza całą wydajność w numpy.

Więc powtórz 3 razy szybko: obiekt == złe, float == dobry

Mówiąc, że wiele operacji może nadal działać tak samo dobrze z Żaden vs NaN (ale być może są nieobsługiwane czyli mogą czasami dać surprising results):

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

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

Aby odpowiedzieć na drugie pytanie:
Powinieneś używać pd.isnull i pd.notnull do testowania brakujących danych (NaN).

+9

po prostu dodając tutaj 2c .... '' np.nan'' pozwala na operacje wektorowe; jest wartością float, podczas gdy '' None'' z definicji wymusza typ 'object'' i zasadniczo wyłącza całą wydajność w numpy, więc powtarzaj 3 razy szybko:' 'object == bad, float == good'' – Jeff

+0

see także: http://stackoverflow.com/a/19866269/1240268 –

2

Funkcja isnan() sprawdza, czy coś jest „Not A Number” i powróci, czy zmienna jest liczbą, na przykład isnan(2) wróci fałszywych

warunkowego myVar is not None zwrotów czy zmienna jest zdefiniowane

Twój numpy tablicy używa isnan() ponieważ ma być tablicą liczb i inicjalizuje wszystkie elementy tablicy do NaN elementy te są uważane za „pusty”

+1

Myślę, że 'isnan (2)' zwróci 'Fałsz', ponieważ 2 nie jest NaN. – heltonbiker

+0

Również 'numpy.empty' nie inicjuje wartości tablicowych na' NaN'. Po prostu nie inicjalizuje wartości. – heltonbiker

+0

@heltonbiker idk o czym myślałem – Stephan

7

NaN może być używana jako wartość numeryczna w operacjach matematycznych, podczas gdy None nie może (a przynajmniej nie powinna).

NaN to wartość liczbowa, zdefiniowana w IEEE 754 floating-point standard. None to wewnętrzny trajk Pythona (NoneType), który bardziej przypomina "nieistniejący" lub "pusty" niż "numerycznie nieważny" w tym kontekście.

Głównym „objaw” o to, że jeśli wykonuje, powiedzmy, średnio lub suma na tablicy zawierającej NaN, nawet ani jednego, masz NaN w wyniku ...

W z drugiej strony nie można wykonywać operacji matematycznych, używając jako argumentu None.

Tak więc, w zależności od przypadku, można użyć None jako sposobu na poinformowanie algorytmu, 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 jest to None.

Numpy ma kilka funkcji, które pozwalają uniknąć wartości NaN, aby zanieczyścić wyniki, na przykład nansum i nan_to_num na przykład.

+0

Zgadzam się z Tobą, że None powinno być używane do nieistniejących wpisów, więc dlaczego 'df = pd.readcsv ('file.csv')' daje mi wartości 'NaN' dla pustych komórek, a nie' Brak'? O ile mi wiadomo, pd.DataFrames nie są wyłącznymi liczbami. – user1083734

+0

Cóż, to prawdopodobnie wybór projektu. Przypuszczam, że DataFrames i Series mają 'dtype', więc niepoprawne wartości' dtype = float' muszą być reprezentowane przez wartości liczbowe, które 'NaN' jest i' None' nie jest ('None' jest' NoneType'). – heltonbiker

+0

Ponadto, wiele metod Pandy ma argument "na", który pozwala ci zdecydować, której wartości użyjesz, aby zastąpić niedostępne wartości. – heltonbiker

Powiązane problemy