2016-01-18 10 views
12

Tôi nghĩ tùy chọn thứ ba được cho là cách nhanh nhất để xóa khoảng trắng? Ai đó có thể cho tôi một số quy tắc chung mà tôi nên áp dụng khi làm việc với các tập dữ liệu lớn không? Tôi thường sử dụng .astype (str) nhưng rõ ràng là không đáng giá cho các cột mà tôi biết là các đối tượng đã có.Hiệu suất của str.strip cho Pandas

%%timeit 
fcr['id'] = fcr['id'].astype(str).map(str.strip) 
10 loops, best of 3: 47.8 ms per loop 

%%timeit 
fcr['id'] = fcr['id'].map(str.strip) 
10 loops, best of 3: 25.2 ms per loop 

%%timeit 
fcr['id'] = fcr['id'].str.strip(' ') 
10 loops, best of 3: 55.5 ms per loop 
+1

nó có thể đáng yêu trên [github] (https://github.com/pydata/pandas/issues) tại sao đây là trường hợp vì đây không phải là những gì tôi mong đợi – EdChum

+1

Tốt nhất nên làm một chút nhiều hồ sơ đầu tiên để xem những gì gây ra sự chậm lại tương đối. Nói chung, hai cái cuối cùng của bạn sẽ không tương đương vì các phương thức '.str' của gấu trúc đều có 1. regexes hoặc strings, 2.) xử lý NaNs mà không bị nổ tung. Có thể thấy những gì trên đầu của những người trông giống như. – TomAugspurger

+1

@TomAugspurger Tôi đã thử nghiệm trên một hàng đơn giản 30k df: 'df = pd.DataFrame ({'id': ['asds', 'as as', 'asdsa asdasdas']}) df = pd.concat ([ df] * 10000, ignore_index = True) 'và quan sát cùng một điều như OP – EdChum

Trả lời

12

Trước hết hãy xem xét sự khác biệt giữa .map(str.strip).str.strip() (trường hợp thứ hai và thứ ba).
Vì vậy, bạn cần phải hiểu những gì str.strip() làm theo mui xe: nó thực sự làm một số map(str.strip), nhưng sử dụng một chức năng tùy chỉnh map sẽ xử lý các giá trị bị thiếu.
Vì vậy, cho rằng .str.strip()có nhiều hơn hơn .map(str.strip), bạn sẽ thấy rằng phương pháp này sẽ luôn chậm hơn (và như bạn đã chỉ ra, trong trường hợp của bạn là 2x chậm hơn).

Sử dụng phương pháp .str.strip() có lợi thế trong xử lý NaN tự động (hoặc xử lý các giá trị không phải chuỗi khác). Giả sử cột 'id' chứa một giá trị NaN:

In [4]: df['id'].map(str.strip) 
... 
TypeError: descriptor 'strip' requires a 'str' object but received a 'float' 

In [5]: df['id'].str.strip() 
Out[5]: 
0     NaN 
1    as asd 
2  asdsa asdasdas 
       ... 
29997    asds 
29998   as asd 
29999 asdsa asdasdas 
Name: id, dtype: object 

Như @EdChum chỉ ra, bạn có thể thực sự sử dụng map(str.strip)nếu bạn có chắc bạn không có bất kỳ giá trị NaN nếu khác biệt hiệu suất này là rất quan trọng.


Quay lại sự khác biệt khác là fcr['id'].astype(str).map(str.strip). Nếu bạn đã biết rằng các giá trị bên trong chuỗi là chuỗi, thực hiện cuộc gọi astype(str) là tất nhiên không cần thiết. Và đó là cuộc gọi này giải thích sự khác biệt:

In [74]: %timeit df['id'].astype(str).map(str.strip) 
100 loops, best of 3: 10.5 ms per loop 

In [75]: %timeit df['id'].astype(str) 
100 loops, best of 3: 5.25 ms per loop 

In [76]: %timeit df['id'].map(str.strip) 
100 loops, best of 3: 5.18 ms per loop 

Lưu ý rằng trong trường hợp bạn có giá trị không theo chuỗi (NaN, giá trị số, ...), sử dụng .str.strip().astype(str).map(str) sẽ không mang lại cùng kết quả:

In [11]: s = pd.Series([' a', 10]) 

In [12]: s.astype(str).map(str.strip) 
Out[12]: 
0  a 
1 10 
dtype: object 

In [13]: s.str.strip() 
Out[13]: 
0  a 
1 NaN 
dtype: object 

Như bạn có thể thấy, .str.strip() sẽ trả về giá trị không phải chuỗi là NaN, thay vì chuyển đổi thành chuỗi.