Làm cách nào để viết thường cột chuỗi khung dữ liệu gấu trúc nếu nó bị thiếu giá trị?


84

Mã sau không hoạt động.

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())

Tôi nên tinh chỉnh nó như thế nào để có xLower = ['one', 'two', np.nan]? Hiệu quả là rất quan trọng vì khung dữ liệu thực là rất lớn.


Từ v0,25 trở đi, tôi khuyên bạn nên str.casefoldso sánh chuỗi gấp trường hợp tích cực hơn. Thêm thông tin trong câu trả lời này .
cs95

Câu trả lời:


180

sử dụng phương pháp chuỗi vector hóa pandas ; như trong tài liệu:

các phương pháp này tự động loại trừ các giá trị bị thiếu / NA

.str.lower() là ví dụ đầu tiên ở đó;

>>> df['x'].str.lower()
0    one
1    two
2    NaN
Name: x, dtype: object

thú vị này là chậm hơn so với các phương pháp bản đồ trong câu trả lời khác 10000 loops, best of 3: 96.4 µs per loopso10000 loops, best of 3: 125 µs per loop
EdChum

1
@EdChum không có gì đáng ngạc nhiên khi chỉ có 3 yếu tố; nhưng sẽ không đúng với trường hợp chỉ có 100 phần tử;
behzad.nouri,

@ behzad.nouri Tôi đã thử df1 ['comment'] = df1 ['comment']. str.lower () nhưng bị lỗi KeyError: 'comment' everythime. Tôi đã kiểm tra - tôi có cột có tên exaclty giống nhau. Điều gì có thể gây ra lỗi?
Katya

16

Một giải pháp khả thi khác, trong trường hợp cột không chỉ có chuỗi mà còn có số, là sử dụng astype(str).str.lower()hoặc to_string(na_rep='')bởi vì nếu không, cho rằng một số không phải là chuỗi, khi hạ xuống nó sẽ trả về NaN, do đó:

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()

sau đó chúng tôi có:

>>> xSecureLower
0    one
1    two
2   
3      2
Name: x, dtype: object

và không

>>> xLower
0    one
1    two
2    NaN
3    NaN
Name: x, dtype: object

biên tập:

nếu bạn không muốn mất NaN, thì sử dụng bản đồ sẽ tốt hơn, (từ @ wojciech-walczak và @ cs95 comment) nó sẽ giống như thế này

xSecureLower = df['x'].map(lambda x: x.lower() if isinstance(x,str) else x)

1
Cảm ơn anh bạn! Tôi quên mất NaNs, tôi vừa sửa câu trả lời
Mike W

7

Một giải pháp khả thi:

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)

Và kết quả là:

0    one
1    two
2    NaN
Name: x, dtype: object

Tuy nhiên, không chắc chắn về hiệu quả.


Tương tự như câu trả lời khác, sử dụng isinstancekhi kiểm tra loại đối tượng.
cs95

6

bạn cũng có thể thử cái này,

df= df.applymap(lambda s:s.lower() if type(s) == str else s)

1
type(s) == strthay vào đó phải làisinstance(s, str)
cs95

6

Gấu trúc> = 0,25: Xóa phân biệt chữ hoa chữ thường với str.casefold

Bắt đầu từ v0.25, tôi khuyên bạn nên sử dụng phương pháp chuỗi "vectơ hóa" str.casefoldnếu bạn đang xử lý dữ liệu unicode (nó hoạt động bất kể chuỗi hay mã unicodes):

s = pd.Series(['lower', 'CAPITALS', np.nan, 'SwApCaSe'])
s.str.casefold()

0       lower
1    capitals
2         NaN
3    swapcase
dtype: object

Cũng xem vấn đề GitHub liên quan GH25405 .

casefoldcho phép chính nó để so sánh gấp trường hợp tích cực hơn. Nó cũng xử lý các NaN một cách duyên dáng (giống như str.lowerhiện tại).

Nhưng tại sao điều này tốt hơn?

Sự khác biệt được nhìn thấy với các mã unicode. Lấy ví dụ trong tài liệu về pythonstr.casefold ,

Viết hoa chữ thường tương tự như viết thường nhưng tích cực hơn vì nó nhằm loại bỏ tất cả các phân biệt chữ hoa và chữ thường trong một chuỗi. Ví dụ, chữ thường trong tiếng Đức 'ß'tương đương với "ss". Vì nó đã là chữ thường, lower()sẽ không làm gì cả 'ß'; casefold() chuyển đổi nó thành "ss".

So sánh đầu ra của lowercho,

s = pd.Series(["der Fluß"])
s.str.lower()

0    der fluß
dtype: object

So với casefold,

s.str.casefold()

0    der fluss
dtype: object

Ngoài ra, hãy xem Python: low () so với casefold () trong đối sánh chuỗi và chuyển đổi thành chữ thường .


2

Có thể đang sử dụng khả năng hiểu Danh sách

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)

2

Áp dụng hàm lambda

df['original_category'] = df['original_category'].apply(lambda x:x.lower())

1

Sử dụng chức năng áp dụng,

Xlower = df['x'].apply(lambda x: x.upper()).head(10) 

1
Vì Hiệu quả là quan trọng đối với người dùng (Efficiency is important since the real data frame is huge.)và còn một số câu trả lời nữa, vui lòng cố gắng chỉ ra câu trả lời nào là điểm tốt trong câu trả lời của bạn.
David García Bodego

0

sao chép cột Dataframe của bạn và chỉ cần áp dụng

df=data['x']
newdf=df.str.lower()
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.