2013-06-05 36 views
6

Có cách nào NumPy mẹ đẻ để chuyển đổi một loạt các cơ quan đại diện chuỗi các phép toán luận ví dụ:NumPy Chuyển đổi chuỗi Đại diện của Boolean Mảng Để mảng Boolean

['True','False','True','False'] 

Để một mảng boolean thực tế tôi có thể sử dụng cho mặt nạ/lập chỉ mục? Tôi có thể làm một vòng lặp cho đi qua và xây dựng lại mảng nhưng đối với mảng lớn này là chậm.

+0

Có một chuỗi mảng NumPy (nếu một điều như vậy tồn tại) hoặc một mảng chuỗi python? – Eric

+0

Đó là một mảng chuỗi dày đặc - kỳ lạ, tôi biết. – Newmu

+1

@Newmu - Tôi nghĩ rằng giải pháp cho điều này là để tránh nhận được một loạt các biểu diễn chuỗi ở nơi đầu tiên. Làm thế nào bạn đến bằng mảng đó? Có lẽ đó là nơi chúng ta nên bắt đầu tìm cách để tối ưu hóa điều này ... – mgilson

Trả lời

6

Bạn sẽ có thể làm một so sánh boolean, IIUC, cho dù dtype là một chuỗi hoặc object:

>>> a = np.array(['True', 'False', 'True', 'False']) 
>>> a 
array(['True', 'False', 'True', 'False'], 
     dtype='|S5') 
>>> a == "True" 
array([ True, False, True, False], dtype=bool) 

hoặc

>>> a = np.array(['True', 'False', 'True', 'False'], dtype=object) 
>>> a 
array(['True', 'False', 'True', 'False'], dtype=object) 
>>> a == "True" 
array([ True, False, True, False], dtype=bool) 
+0

+1 - Vì vậy, ... đơn giản. – mgilson

+0

Điều kỳ diệu khi phát sóng? Ngoài ra nó nhanh (20x nhanh hơn so với câu trả lời khác). – Newmu

+0

@Newmu Và chuỗi thực tập, nếu tôi không nhầm (ít nhất, tất cả các mục trong 'a' là' 'True'' có cùng giá trị cho 'id()', cũng là trường hợp cho tất cả '' Các phần tử False'' [mặc dù kỳ quặc, 'is' không xuất hiện để làm việc cho các phần tử đó. Trong thực tế nó không hoạt động ngay cả khi bạn kiểm tra một mục nhập với chính nó' a [0] là một [0] 'trả về' Sai ', mặc dù' id (a [0]) == id (a [0]) 'trả về' True']) Tôi tin rằng interning là lý do tại sao kiểm tra bình đẳng ở đây nhanh hơn rất nhiều so với 'numpy.char.startswith() 'mặc dù các hàm trong' numpy.char' có nghĩa vụ thực hiện các phép toán chuỗi nhanh trên các mảng numpy. – JAB

0

Điều này có đủ tốt không?

my_list = ['True', 'False', 'True', 'False'] 
np.array(x == 'True' for x in my_list) 

Nó không phải là bản địa, nhưng nếu bạn đang bắt đầu với danh sách không phải là gốc, nó thực sự không quan trọng.

+1

Điều đó sẽ không hoạt động như được viết vì không có kết quả tốt với biểu thức trình tạo. – DSM

+0

Đấm bốc nó như là một danh sách comp công trình nhưng nó là 20x chậm hơn so với câu trả lời của DSM cho mảng với hơn một vài nghìn giá trị. – Newmu

2

Tôi đã tìm thấy một phương pháp mà thậm chí còn nhanh hơn DSM, lấy cảm hứng từ Eric, mặc dù sự cải thiện được nhìn thấy rõ nhất với các danh sách giá trị nhỏ hơn; ở các giá trị rất lớn, chi phí của việc lặp lại chính nó bắt đầu lớn hơn lợi thế của việc thực hiện kiểm tra sự thật trong quá trình tạo mảng numpy thay vì sau. Thử nghiệm với cả hai is== (đối với các tình huống trong đó các chuỗi được tập trung so với khi chúng có thể không được, vì is sẽ không hoạt động với các chuỗi không phải là nội bộ.) cho thấy rằng trong khi phiên bản của tôi với == chậm hơn so với is, nó vẫn nhanh hơn nhiều so với phiên bản DSM.

thử nghiệm thiết lập:

import timeit 
def timer(statement, count): 
    return timeit.repeat(statement, "from random import choice;import numpy as np;x = [choice(['True', 'False']) for i in range(%i)]" % count) 

>>> stateIs = "y = np.fromiter((e is 'True' for e in x), bool)" 
>>> stateEq = "y = np.fromiter((e == 'True' for e in x), bool)" 
>>> stateDSM = "y = np.array(x) == 'True'" 

Với 1.000 mặt hàng, báo cáo nhanh mất khoảng 66% thời gian của DSM:

>>> timer(stateIs, 1000) 
[101.77722641656146, 100.74985342340369, 101.47228618107965] 
>>> timer(stateEq, 1000) 
[112.26464996250706, 112.50754567379681, 112.76057346127709] 
>>> timer(stateDSM, 1000) 
[155.67689949529995, 155.96820504501557, 158.32394669279802] 

Đối với mảng chuỗi nhỏ hơn (trong hàng trăm chứ không phải hàng ngàn), thời gian trôi qua nhỏ hơn 50% của DSM:

>>> timer(stateIs, 100) 
[11.947757485669172, 11.927990253608186, 12.057855628259858] 
>>> timer(stateEq, 100) 
[13.064947253943501, 13.161545451986967, 13.30599035623618] 
>>> timer(stateDSM, 100) 
[31.270060799078237, 30.941749748808434, 31.253922641324607] 

Một chút hơn 25% DSM khi hoàn tất với 50 mặt hàng theo danh sách:

>>> timer(stateIs, 50) 
[6.856538342483873, 6.741083326021908, 6.708402786859551] 
>>> timer(stateEq, 50) 
[7.346079345032194, 7.312723444475523, 7.309259899921017] 
>>> timer(stateDSM, 50) 
[24.154247576229864, 24.173593700599667, 23.946403452288905] 

Đối với 5 mặt hàng, khoảng 11% của DSM:

>>> timer(stateIs, 5) 
[1.8826215278058953, 1.850232652068371, 1.8559381315990322] 
>>> timer(stateEq, 5) 
[1.9252821868467436, 1.894011299061276, 1.894306935199893] 
>>> timer(stateDSM, 5) 
[18.060974208809057, 17.916322392367874, 17.8379771602049] 
+1

Bạn có nhận thấy rằng tất cả chúng đều là 'True' trong kết quả không? :-P – mgilson

+0

.. không phải là chuỗi không đúng, mặc dù, ngay cả khi chúng "Sai" .. – DSM

+0

@DSM Câu trả lời mới của tôi dường như là một cải tiến lớn so với cái cũ của tôi. – JAB

Các vấn đề liên quan