【发布时间】:2012-06-15 14:12:03
【问题描述】:
Python 的 numpy 库对精美索引的“矢量化”有时会产生意想不到的结果。例如:
import numpy
a = numpy.zeros((1000,4), dtype='uint32')
b = numpy.zeros((1000,4), dtype='uint32')
i = numpy.random.random_integers(0,999,1000)
j = numpy.random.random_integers(0,3,1000)
a[i,j] += 1
for k in xrange(1000):
b[i[k],j[k]] += 1
在数组 'a' 和 'b' 中给出不同的结果(即元组 (i,j) 的出现在 'a' 中显示为 1 而与重复无关,而在 'b' 中计算重复)。这很容易验证如下:
numpy.sum(a)
883
numpy.sum(b)
1000
同样值得注意的是,花哨的索引版本几乎比 for 循环快两个数量级。我的问题是:“numpy 是否有一种有效的方法来计算重复计数,如在提供的示例中使用 for 循环实现的那样?”
【问题讨论】:
-
语义不同:for循环按顺序工作(重复索引的值递增多次),但
a += 1等价于a = a + 1(重复索引递增一次)。 -
我知道语义上存在差异(我不应该在我的原始帖子中说“意外”),但是有没有一种有效的方法来计算 for 循环语义(即计算 ( i,j) 元组) 使用 numPy?
-
懒惰的选择是使用 Cython。它可能比基于函数的 numpy 版本更快、更易读。尽管后来的力量以更笼统的方式考虑操作(这可能是一件好事),但最终的解决方案可能更具可扩展性,例如stackoverflow.com/questions/4962606/…