【发布时间】:2021-01-30 17:41:47
【问题描述】:
我有两个数组p 和alpha,我想<=-比较p 的每个元素与alpha 的每个元素,然后在第一个轴上聚合(计数)。我的代码:
s = np.sum(np.less_equal.outer(p, alpha), axis=0)
p 至少是一维的,但也可能是多维的,可以有 100 × 1000000 这样的维度。alpha 是一维的,通常有 100 到 1000 个元素。
问题是np.less_equal.outer 创建了一个中间数组,在最坏的情况下,它的大小可能是 100 × 1000000 × 1000 = 1011 个元素,接近 1 TB,远远超出我的记忆容量。
我的方法是沿第一个轴拆分计算:
s = np.zeros(shape=(*p.shape[1:], len(alpha)), dtype='int64')
for pr in p:
s += np.less_equal.outer(pr, alpha)
这似乎可行,但我想知道 NumPy 是否有工具可以提高效率(矢量化)?
【问题讨论】:
-
我们在
numpy中所说的“矢量化”是第一种方法,即制作大型中间数组。那是使用已编译的 numpy 方法,并且对于中等大小的数组来说很快。但是随着更大的情况,内存管理变得更加复杂并减慢了速度。然后在相对复杂的任务上进行适度数量的迭代会更好。除非你想使用像numba这样的编译工具。 -
@hpaulj 所以因为我在最短的轴上进行迭代,这意味着我的解决方案尽可能高效(无需编译)?
-
大概.so。只有时间可以证明这一点。
-
PS:“vecorized”是指编译后的例程,相当于我的
sum和*.outer的组合,而不实际生成中间数组。 -
我想最简单的方法(而且速度更快)是将其写在一个简单的循环中并使用 Cython 或 Numba 进行编译。这将避免任何临时数组。这非常相似:stackoverflow.com/a/58189944/4045774
标签: python numpy numpy-ndarray