我有下面的代码,完全可以做我想要的,但是太慢了,因为它涉及不必要的具体化步骤:
### init
a = np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
### condition 1) element 0 has to be larger than 1
### condition 2) limit the output to 2 elements
b = a[a[:,0] > 1][:2]
问题是当我有一个大数组时,这个过程非常慢(假设我只想用条件2切掉一小块)。这是很容易做到的,但我还没有找到一种方法把它放在一条直线上。在
因此,有没有一种简洁的方法可以在一个一行代码中有效地完成这一任务?像这样:
^{pr2}$谢谢你!在
我想不出在直接numpy中更快的解决方案,但是您可能可以使用
numba
做得更好:以下是另外两个建议的解决方案供参考:
^{pr2}$一些时间安排:
^{3}$您可能可以将此代码加快一点,您当前的代码如下所示:
我怀疑最昂贵的操作是中间的复制操作,您可以尝试这样做来避免它,方法是:
^{pr2}$可能有一种更有效的方法来找到前两个真值,我没有考虑太多,但关键是先找到您想要的值,然后只复制这些行。在
如果}相比非常小,那么使用这个小函数可能是值得的。其基本思想是计算一个足够大的掩码,以提供所需的最终行数。在这里我迭代地做。通常迭代很慢,但是如果迭代次数足够少,那么在别处节省的时间是值得的。在
n=2
与{请注意,掩码
am
可以比它正在处理的维度短。它有效地用False
填充其余部分。我还没检查这是否有记录。在在这个小例子中,
foo
比a[a[:,0]>1,:][:2,:]
慢3倍。在但是对于一个更大的数组,比如
a2=np.tile(a,[1000,1])
,使用foo
的时间保持不变,但是“蛮力”不断变慢,因为它必须将掩码应用到更多行。当然,这些计时确实取决于a
中期望行的位置。如果foo
必须使用几乎所有的行,则不会有任何节省。在编辑
为了解决Bi-Rico对重复的
^{pr2}$np.sum
(即使是快速编译的代码),我们可以逐步构建where
:对于小的
n
这甚至更快。在更接近原始方法的方法是计算完整的遮罩,然后进行修剪。
^{3}$cumsum
可用于查找最小长度。在用
1000x1000
随机整数数组(1:12)测试,times为(使用20而不是2,并调整掩码以使更多的行为假)rico_filter
使用where
是最快的,但是我的另一种使用cumsum
的方法并不落后。3个增量过滤器的速度相似,大约是快速过滤器的一半。在在这个生成并测试的
a
中,大多数行是True
。这与marco's
关注的极限条件是逻辑条件的一个小子集是一致的。在这些条件下,比里科担心paul_filter1
可能爆炸是不现实的。在如果我更改了测试参数,那么
a
的所有行都必须被测试(a[:,0]>11
), 然后使用where
和cumsum
的过滤器所用的时间与原始过滤器一样长。增量过滤器速度较慢,为15倍或更多。但我第一次尝试使用np.sum
是这种风格中最快的。在相关问题 更多 >
编程相关推荐