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.

Mark Morrisson
źródło
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:

123

po prostu użyj replace:

In [106]:
df.replace('N/A',np.NaN)

Out[106]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN

To, czego próbujesz, nazywa się indeksowaniem łańcuchowym: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

locAby upewnić się, że pracujesz na oryginalnym dF, możesz użyć :

In [108]:
df.loc[df['y'] == 'N/A','y'] = np.nan
df

Out[108]:
    x    y
0  10   12
1  50   11
2  18  NaN
3  32   13
4  47   15
5  20  NaN
EdChum
źródło
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
Severin Pappadeux
źródło
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ń

jmorrison
źródło
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.

slevin886
źródło
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ć.

jeremie benichou
źródło
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
rolandpeng
źródło
0

df.replace ('columnvalue', np.NaN, inplace = True)

sameer_nubia
źródło