2017-06-14 37 views
10

設置
考慮numpy的陣列a如何做一個累積的「所有」

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

問題
對於每一列,我要確定的累計相當於所有。

結果應該是這樣的:

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) 

就拿第一列

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 

所以基本上,累計全是True只要我們有True並在從此開啓False上第一個False


我已經試過
我能得到的結果與

a.cumprod(0).astype(bool) 

不過,我不禁想知道如果在必要的時候,我知道一切都會從第一False執行每個乘法False我明白了。

考慮較大的1-d陣列

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

我主張這兩個產生相同的答案

bool(b.prod()) 

b.all() 

但是b.all()可以短路而b.prod()確實不。如果我次地:

%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()更快。這意味着,必須有我的方式來進行累積所有的更快,我a.cumprod(0).astype(bool)

+0

IIRC,所述'上NumPy的陣列實際上要麼不短路,或僅all'方法在處理完整個數組塊後發生短路,以獲得相當大的(默認)塊大小。 – user2357112

+0

我們在其他SO問題中發現選定的操作會造成短路,例如涉及'nan'的'min/max'。但我的猜測是,大多數(如果不是全部的話)'ufunc'使用泛型迭代器來執行'accumulate'。當沿一個軸進行工作時尤其如此。在列情況下短路需要停止在每列的不同行。 – hpaulj

回答

13

All ufuncs have 5 methodsreduceaccumulatereduceatouterat。在這種情況下,使用accumulate因爲它返回的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)'是一個更公平的比較,它本質上是相同的速度。使用'astype'招致副本 – Eric

+0

更好的問題是爲什麼你不把它作爲答案? – piRSquared

+1

'np.minimum.accumulate(a,axis = 0)'也起作用(相同的速度)。 – hpaulj