Jak ustawić komórkę na NaN w ramce danych pandy


98

Chciałbym zamienić złe wartości w kolumnie ramki danych na wartości NaN.

mydata = {'x' : [10, 50, 18, 32, 47, 20], 'y' : ['12', '11', 'N/A', '13', '15', 'N/A']}
df = pd.DataFrame(mydata)

df[df.y == 'N/A']['y'] = np.nan

Chociaż ostatnia linia zawodzi i generuje ostrzeżenie, ponieważ działa na kopii df. Więc jaki jest właściwy sposób radzenia sobie z tym? Widziałem wiele rozwiązań z iloc lub ix, ale tutaj muszę użyć warunku logicznego.


Wydaje mi się, że tytuł wprowadza w błąd. Problem nie polega na tym, że chcesz mieć NaN w swojej ramce danych. Problem polega na tym, że „próbujesz ustawić się na kopii wycinka z DataFrame”.
Teepeemm

Odpowiedzi:



13

Chociaż użycie replacewydaje się rozwiązywać problem, chciałbym zaproponować alternatywę. Problem z pomieszaniem wartości liczbowych i niektórych łańcuchów w kolumnie, aby nie zastępować łańcuchów np.nan, ale aby cała kolumna była poprawna. Założę się, że oryginalna kolumna jest najprawdopodobniej typu obiektowego

Name: y, dtype: object

To, czego naprawdę potrzebujesz, to uczynić ją kolumną numeryczną (będzie miała odpowiedni typ i byłaby znacznie szybsza), z wszystkimi wartościami nienumerycznymi zastąpionymi przez NaN.

Zatem dobry byłby kod konwersji

pd.to_numeric(df['y'], errors='coerce')

Określ, errors='coerce'aby wymusić na ciągach, których nie można przeanalizować na wartość liczbową, na NaN. Typ kolumny to

Name: y, dtype: float64

10

Możesz użyć zamiany:

df['y'] = df['y'].replace({'N/A': np.nan})

Pamiętaj również o inplaceparametrze for replace. Możesz zrobić coś takiego:

df.replace({'N/A': np.nan}, inplace=True)

Spowoduje to zastąpienie wszystkich instancji w pliku df bez tworzenia kopii.

Podobnie, jeśli napotkasz inne typy nieznanych wartości, takie jak pusty ciąg lub wartość Brak:

df['y'] = df['y'].replace({'': np.nan})

df['y'] = df['y'].replace({None: np.nan})

Odniesienie: Najnowsze Pandy - Wymień


2

Od wersji pandas 1.0.0 nie musisz już używać numpy do tworzenia wartości null w ramce danych. Zamiast tego możesz po prostu użyć pandas.NA (który jest typu pandas._libs.missing.NAType), więc będzie traktowany jako pusty w ramce danych, ale nie będzie zerowy poza kontekstem ramki danych.


Chociaż to nie rozwiązuje problemu OP, zagłosowałem za mną, ponieważ faktycznie odpowiedział na pytanie w tytule.
Teepeemm

1
df.loc[df.y == 'N/A',['y']] = np.nan

To rozwiąże twój problem. Z podwójnym [] pracujesz na kopii DataFrame. Musisz podać dokładną lokalizację w jednym wywołaniu, aby móc ją zmodyfikować.


0

Możesz spróbować tych fragmentów.

W [16]: mydata = {'x': [10, 50, 18, 32, 47, 20], 'y': ['12', '11', 'N / A', '13', ' 15 ',' nie dotyczy ']}
W [17]: df = pd.DataFrame (mydata)

W [18]: df.y [df.y == "nie dotyczy"] = np.nan

Wyj [19]: df 
    xy
0 10 12
1 50 11
2 18 NaN
3 32 13
4 47 15
5 20 NaN

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.