2017-06-14 114 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