Poniższy kod nie działa.
import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan],columns=['x'])
xLower = df["x"].map(lambda x: x.lower())
Jak powinienem to zmienić, aby uzyskać xLower = ['one', 'two', np.nan]? Wydajność jest ważna, ponieważ rzeczywista ramka danych jest ogromna.
python
string
pandas
missing-data
P.Escondido
źródło
źródło
str.casefold
bardziej agresywne porównania ciągów ze składaniem wielkości liter. Więcej informacji w tej odpowiedzi .Odpowiedzi:
używaj pand wektoryzowanych metod ciągów ; jak w dokumentacji:
.str.lower()
to pierwszy przykład;>>> df['x'].str.lower() 0 one 1 two 2 NaN Name: x, dtype: object
źródło
10000 loops, best of 3: 96.4 µs per loop
porównaniu z10000 loops, best of 3: 125 µs per loop
Innym możliwym rozwiązaniem, w przypadku gdy kolumna zawiera nie tylko łańcuchy, ale także liczby, jest użycie
astype(str).str.lower()
lubto_string(na_rep='')
ponieważ w przeciwnym razie, biorąc pod uwagę, że liczba nie jest łańcuchem, po obniżeniu zwróciNaN
, dlatego:import pandas as pd import numpy as np df=pd.DataFrame(['ONE','Two', np.nan,2],columns=['x']) xSecureLower = df['x'].to_string(na_rep='').lower() xLower = df['x'].str.lower()
potem będzie:
>>> xSecureLower 0 one 1 two 2 3 2 Name: x, dtype: object
i nie
>>> xLower 0 one 1 two 2 NaN 3 NaN Name: x, dtype: object
edytować:
jeśli nie chcesz zgubić NaNów, to lepiej będzie używać mapy (od @ wojciech-walczak i komentarza @ cs95) będzie wyglądać mniej więcej tak
xSecureLower = df['x'].map(lambda x: x.lower() if isinstance(x,str) else x)
źródło
możesz spróbować również tego,
df= df.applymap(lambda s:s.lower() if type(s) == str else s)
źródło
type(s) == str
zamiast tego powinno byćisinstance(s, str)
Możliwe rozwiązanie:
import pandas as pd import numpy as np df=pd.DataFrame(['ONE','Two', np.nan],columns=['x']) xLower = df["x"].map(lambda x: x if type(x)!=str else x.lower()) print (xLower)
A wynik:
0 one 1 two 2 NaN Name: x, dtype: object
Nie jestem jednak pewien co do wydajności.
źródło
isinstance
podczas sprawdzania typu obiektu.Pandy> = 0,25: Usuń rozróżnienia wielkości liter za pomocą
str.casefold
Począwszy od wersji 0.25, polecam użycie metody ciągów „wektoryzowanych”,
str.casefold
jeśli masz do czynienia z danymi Unicode (działa niezależnie od ciągu znaków lub Unicode):s = pd.Series(['lower', 'CAPITALS', np.nan, 'SwApCaSe']) s.str.casefold() 0 lower 1 capitals 2 NaN 3 swapcase dtype: object
Zobacz także powiązany problem z usługą GitHub GH25405 .
casefold
nadaje się do bardziej agresywnego porównania składania skrzynek. Z wdziękiem obsługuje również NaN (tak jakstr.lower
).Ale dlaczego to jest lepsze?
Różnica jest widoczna w przypadku Unicode. Biorąc przykład z dokumentacji Pythona
str.casefold
,Porównaj dane wyjściowe
lower
dla,s = pd.Series(["der Fluß"]) s.str.lower() 0 der fluß dtype: object
Versus
casefold
,s.str.casefold() 0 der fluss dtype: object
Zobacz także Python: lower () vs. casefold () w dopasowywaniu ciągów i konwertowaniu na małe litery .
źródło
Może używać rozumienia z list
import pandas as pd import numpy as np df=pd.DataFrame(['ONE','Two', np.nan],columns=['Name']}) df['Name'] = [str(i).lower() for i in df['Name']] print(df)
źródło
Zastosuj funkcję lambda
df['original_category'] = df['original_category'].apply(lambda x:x.lower())
źródło
Użyj funkcji zastosuj,
Xlower = df['x'].apply(lambda x: x.upper()).head(10)
źródło
(Efficiency is important since the real data frame is huge.)
i jest jeszcze kilka odpowiedzi, spróbuj ujawnić, która z nich jest dobrym punktem odpowiedzi.skopiuj kolumnę Dataframe i po prostu zastosuj
df=data['x'] newdf=df.str.lower()
źródło