如果我想比较两个数组,比如说我想测试A中的所有元素是否小于B中的值,我使用if (A < B).all():
。但实际上,这需要分配和评估完整数组C = A < B
,然后在其上调用C.all()
。这有点浪费。有没有办法'快捷'比较,即直接按元素评估A < B
(不分配和计算临时C
),并在第一个无效元素比较时停止并返回False
发现?
答案 0 :(得分:1)
你的阵列有多大?我会想象它们非常大,例如在性能成为问题之前A.shape = (1000000)
或更大。你会考虑使用numpy views吗?
您可以尝试定义视图,例如(A < B).all()
,而不是比较(A < B).any()
或(A[:10] < B[:10]).all()
。这是一个可能有效的简单循环:
k = 0
while( (A[k*10: (k+1)*10] < B[k*10: (k+1)*10] ).all() ):
k += 1
您可以使用100或10**3
段大小而不是10。显然,如果您的细分受众群大小为1,则说:
k = 0
while ( A[k] < B[k] ):
k+= 1
有时,比较整个阵列可能会占用大量内存。如果A
和B
的长度为10000,并且我需要比较每对元素,那么我将耗尽空间。
答案 1 :(得分:0)
普通Python and
和or
使用快捷方式评估,但numpy
没有。
(A < B).all()
使用numpy
构建基块,广播,逐元素与<
的比较以及all
缩减。 <
只适用于其他二元操作,加上,时间和,或,或,等等。all
与其他缩减方法any
,max
一样, sum
,mean
,可以对整个数组或按行或按列进行操作。
可以编写一个将all
和<
组合成一个迭代的函数,但是很难得到我刚才描述的一般性。
但是如果您必须使用快捷操作实现迭代解决方案并快速执行,我建议使用nditer
开发该想法,然后使用cython
进行编译。< / p>
http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html是使用nditer
的好教程,它会引导您在cython
中使用它。 nditer
负责广播和迭代,让您专注于比较和任何捷径。
这是一个可以投射到cython
的迭代器的草图:
import numpy as np
a = np.arange(4)[:,None]
b = np.arange(2,5)[None,:]
c = np.array(True)
it = np.nditer([a, b, c], flags=['reduce_ok'],
op_flags = [['readonly'], ['readonly'],['readwrite']])
for x, y, z in it:
z[...] = x<y
if not z:
print('>',x,y)
break
else:
print(x,y)
print(z)
运行示例:
1420:~/mypy$ python stack34852272.py
(array(0), array(2))
(array(0), array(3))
(array(0), array(4))
(array(1), array(2))
(array(1), array(3))
(array(1), array(4))
('>', array(2), array(2))
False
以默认False
和其他break
条件开头,您可以获得快捷方式any
。推广测试以处理<
,<=
等将会更有效。
使用Python工作,然后在Cython中尝试。如果您在执行该步骤时遇到问题,请返回一个新问题。 SO拥有Cython用户的良好基础。