Chcę znaleźć wszystkie wartości w ramce danych Pandas, które zawierają białe znaki (dowolną ilość) i zastąpić te wartości NaN.
Jakieś pomysły, jak można to poprawić?
Zasadniczo chcę to zmienić:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz
2000-01-05 -0.222552 4
2000-01-06 -1.176781 qux
Zaangażowany w to:
A B C
2000-01-01 -0.532681 foo 0
2000-01-02 1.490752 bar 1
2000-01-03 -1.387326 foo 2
2000-01-04 0.814772 baz NaN
2000-01-05 -0.222552 NaN 4
2000-01-06 -1.176781 qux NaN
Udało mi się to zrobić z poniższym kodem, ale stary czy to brzydkie. To nie jest Pythonic i jestem pewien, że nie jest to również najbardziej efektywne wykorzystanie pand. Przechodzę w pętli przez każdą kolumnę i zastępuję wartość logiczną względem maski kolumny wygenerowanej przez zastosowanie funkcji, która wyszukuje wyrażenia regularne każdej wartości, dopasowując je do białych znaków.
for i in df.columns:
df[i][df[i].apply(lambda i: True if re.search('^\s*$', str(i)) else False)]=None
Można go nieco zoptymalizować, przechodząc tylko przez pola, które mogą zawierać puste ciągi:
if df[i].dtype == np.dtype('object')
Ale to nie jest duża poprawa
I wreszcie, ten kod ustawia ciągi docelowe na None, co działa z takimi funkcjami Pandy, jak fillna()
, ale byłoby miło dla kompletności, gdybym mógł wstawić NaN
bezpośrednio zamiast None
.
replace
z wyrażeniem regularnym ... (być może powinno to być wymagane jako funkcja).Odpowiedzi:
Myślę, że
df.replace()
spełnia swoje zadanie, ponieważ pandy 0.13 :Produkuje:
Jak wskazał Temak , użyj,
df.replace(r'^\s+$', np.nan, regex=True)
jeśli twoje prawidłowe dane zawierają spacje.źródło
pd.Series(["1", "#", "9", " .", None]).replace(r"( +\.)|#", "X", regex=True).values
co daje['1', 'X', '9', 'X', None]
df.replace(r'^\s+$', np.nan, regex=True)
Jeśli chcesz zastąpić pusty ciąg i rekordy tylko spacjami, prawidłowa odpowiedź to !:
Zaakceptowana odpowiedź
Nie zastępuje pustego ciągu !, możesz spróbować z podanym przykładem nieco zaktualizowanym:
Zwróć też uwagę, że „fo o” nie jest zastępowane przez Nan, chociaż zawiera spację. Dalej zauważ, że proste:
To też nie działa - wypróbuj.
źródło
Co powiesz na:
applymap
Funkcja ma zastosowanie funkcji do każdej komórce dataframe.źródło
isinstance
będzie trochę szybszy.''
. Aby wziąć pod uwagę również puste łańcuchy, użyj:d = d.applymap(lambda x: np.nan if isinstance(x, basestring) and (not x or x.isspace()) else x)
Zrobię to:
lub
Możesz usunąć wszystkie str, a następnie zamienić puste str na
np.nan
.źródło
Najprostsze ze wszystkich rozwiązań:
źródło
Jeśli eksportujesz dane z pliku CSV, może to być tak proste:
Spowoduje to utworzenie ramki danych oraz zastąpienie pustych wartości jako Na
źródło
skipinitialspace=True
usuwa również wszelkie białe znaki po separatorze, które spowodowałyby odczytanie dowolnej długości białych znaków i pustych ciągów jakonan
. Jeśli jednak chcesz zachować początkowe spacje z jakiegokolwiek powodu, ta opcja nie jest dobrym wyborem.Aby uzyskać bardzo szybkie i proste rozwiązanie, w którym sprawdzasz równość z pojedynczą wartością, możesz użyć tej
mask
metody.źródło
Wszystko to jest bliskie właściwej odpowiedzi, ale nie powiedziałbym, że żaden problem rozwiązuje problem, pozostając najbardziej czytelnym dla innych czytających Twój kod. Powiedziałbym, że ta odpowiedź jest połączeniem odpowiedzi BrenBarna i komentarza tuomasttik pod tą odpowiedzią . Odpowiedź BrenBarn wykorzystuje
isspace
wbudowane, ale nie obsługuje usuwania pustych ciągów, zgodnie z żądaniem OP, i miałbym tendencję do przypisywania tego jako standardowego przypadku zastępowania ciągów przez null.Przepisałem to za pomocą
.apply
, więc możesz to nazwać napd.Series
lubpd.DataFrame
.Python 3:
Aby zamienić puste ciągi lub ciągi całkowicie spacji:
Aby zamienić ciągi całkowicie spacji:
W tym celu użyć w Pythonie 2, trzeba wymienić
str
zbasestring
.Python 2:
Aby zamienić puste ciągi lub ciągi całkowicie spacji:
Aby zamienić ciągi całkowicie spacji:
źródło
To zadziałało dla mnie. Kiedy importuję mój plik csv, dodałem na_values = ''. Spacje nie są uwzględniane w domyślnych wartościach NaN.
df = pd.read_csv (ścieżka pliku, na_values = '')
źródło
możesz też użyć do tego filtra.
źródło
źródło
To nie jest eleganckie rozwiązanie, ale wydaje się, że działa, to zapisywanie do XLSX, a następnie importowanie go z powrotem. Inne rozwiązania na tej stronie nie działają dla mnie, nie jestem pewien dlaczego.
źródło