2017-06-14 24 views
10

Cài đặt
Hãy xem xét những mảng NumPy aLàm thế nào để làm một tích lũy "tất cả"

>>> np.random.seed([3,1415]) 
>>> a = np.random.choice([True, False], (4, 8)) 

>>> a 
array([[ True, False, True, False, True, True, False, True], 
     [False, False, False, False, True, False, False, True], 
     [False, True, True, True, True, True, True, True], 
     [ True, True, True, False, True, False, False, False]], dtype=bool) 

Câu hỏi
Đối với mỗi cột, tôi muốn xác định tương đương với tích lũy cho tất cả.

Kết quả sẽ giống như thế này:

array([[ True, False, True, False, True, True, False, True], 
     [False, False, False, False, True, False, False, True], 
     [False, False, False, False, True, False, False, True], 
     [False, False, False, False, True, False, False, False]], dtype=bool) 

Hãy cột đầu tiên

a[: 0] 

# Original First Column 
array([ True, False, False, True], dtype=bool) 
# So far so good 
#  \  False from here on 
#   | /---------------\ 
array([ True, False, False, False], dtype=bool) 
# Cumulative all 

Vì vậy, về cơ bản, tích lũy tất cả là True miễn là chúng ta có True và biến False từ đó trở đi tại đầu tiên False


Những gì tôi đã cố gắng
tôi có thể nhận được kết quả với

a.cumprod(0).astype(bool) 

Nhưng, tôi không thể không tự hỏi nếu nó cần thiết để thực hiện mỗi nhân khi tôi biết mọi thứ sẽ False từ đầu tiên False Tôi hiểu.

xem xét lớn hơn 1-D mảng

b = np.array(list('111111111110010101010101010101010101010011001010101010101')).astype(int).astype(bool) 

Tôi cho rằng hai tạo ra câu trả lời tương tự

bool(b.prod()) 

b.all() 

Nhưng b.all() có thể ngắn mạch trong khi b.prod() làm không phải. Nếu tôi thời gian cho họ:

%timeit bool(b.prod()) 
%timeit b.all() 

100000 loops, best of 3: 2.05 µs per loop 
1000000 loops, best of 3: 1.45 µs per loop 

b.all() là nhanh hơn. Điều này ngụ ý rằng có phải tôi một cách để tiến hành một tích lũy tất cả những gì là nhanh hơn mà tôi a.cumprod(0).astype(bool)

+0

IIRC, 'cái all' phương pháp trên NumPy mảng thực sự hoặc không ngắn mạch hoặc chỉ ngắn mạch sau khi xử lý một đoạn hoàn chỉnh của mảng, đối với một số kích thước khá lớn (mặc định) chunk. – user2357112

+0

Chúng tôi đã tìm thấy trong các câu hỏi SO khác mà các hoạt động đã chọn thực hiện ngắn mạch, chẳng hạn như 'min/max' liên quan đến' nan'. Nhưng tôi đoán là hầu hết, nếu không phải tất cả, 'ufunc' sử dụng một trình lặp chung để thực hiện' tích lũy'. Điều đó đặc biệt đúng khi làm việc dọc theo một trục.Ngắn mạch trong trường hợp cột của bạn sẽ yêu cầu dừng lại ở các hàng khác nhau cho mỗi cột. – hpaulj

Trả lời

13

All ufuncs have 5 methods: reduce, accumulate, reduceat, outer, và at. Trong trường hợp này, sử dụng accumulate vì nó trả về kết quả của các ứng dụng tích lũy của ufunc:

In [41]: np.logical_and.accumulate(a, axis=0) 
Out[50]: 
array([[ True, False, True, False, True, True, False, True], 
     [False, False, False, False, True, False, False, True], 
     [False, False, False, False, True, False, False, True], 
     [False, False, False, False, True, False, False, False]], dtype=bool) 

In [60]: np.random.seed([3,1415]) 

In [61]: a = np.random.choice([True, False], (400, 80)) 

In [57]: %timeit np.logical_and.accumulate(a, axis=0) 
10000 loops, best of 3: 85.6 µs per loop 

In [59]: %timeit a.cumprod(0).astype(bool) 
10000 loops, best of 3: 138 µs per loop 
+2

'a.cumprod (0, dtype = bool)' là một so sánh công bằng hơn nhiều, về cơ bản là cùng một tốc độ. Sử dụng 'astype' phát sinh một bản sao – Eric

+0

Câu hỏi hay hơn là tại sao bạn không đăng câu trả lời đó? – piRSquared

+1

'np.minimum.accumulate (a, axis = 0)' cũng hoạt động (cùng tốc độ). – hpaulj

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