【问题标题】:Fast indexed dot-product for numpy/scipynumpy/scipy 的快速索引点积
【发布时间】:2015-03-21 01:29:10
【问题描述】:

我正在使用 numpy 来做线性代数。我想做快速子集索引 dot 和其他线性操作。

在处理大矩阵时,像A[:,subset].dot(x[subset]) 这样的切片解决方案可能比对整个矩阵进行乘法运算要长。

A = np.random.randn(1000,10000)
x = np.random.randn(10000,1)
subset = np.sort(np.random.randint(0,10000,500))

时间表明,当列在一个块中时,子索引可以更快。

%timeit A.dot(x)
100 loops, best of 3: 4.19 ms per loop

%timeit A[:,subset].dot(x[subset])
100 loops, best of 3: 7.36 ms per loop

%timeit A[:,:500].dot(x[:500])
1000 loops, best of 3: 1.75 ms per loop

仍然不是我所期望的加速(快 20 倍!)。

有谁知道允许通过 numpy 或 scipy 进行此类快速操作的库/模块的想法?

现在我正在使用 cython 通过 cblas 库编写快速的列索引点积。但对于更复杂的操作(伪逆或子索引最小二乘求解),我不保证达到良好的加速度。

谢谢!

【问题讨论】:

  • 您为什么期望 20 倍加速?
  • 天真地,计算 10000 列的结果应该比计算 500 快 20 倍。

标签: python numpy scipy cython blas


【解决方案1】:

嗯,这样更快。

%timeit A.dot(x)
#4.67 ms

%%timeit
y = numpy.zeros_like(x)
y[subset]=x[subset]
d = A.dot(y)
#4.77ms

%timeit c = A[:,subset].dot(x[subset])
#7.21ms

你有all(d-ravel(c)==0) == True

请注意,这有多快取决于输入。使用subset = array([1,2,3]),我的解决方案的时间几乎相同,而最后一个解决方案的时间是46micro seconds

如果subset 的大小不小于x 的大小,基本上这会更快

【讨论】:

  • 是的,但我距离预期的 20 倍加速还差得很远。
  • 您不能期望 20 倍的加速,因为您正在处理不连续的数据,这可能会导致计算速度变慢
  • 是的,你是对的,但是当处理'F'连续数组时,你可以达到很好的加速,例如使用 cblas 库的 cython 接口。如果有模块可以以易于使用的方式实现类似或更好的加速,并且用于更复杂的操作,我实际上是在徘徊。
  • 使用随机索引,顺序是F还是C都没关系。看A[:,subset]的时间。这比在 500 列上执行 dot 大得多。
  • 是的,这实际上是我的问题。那么有没有办法在不切片/索引的情况下进行这样的计算,以避免分配新数组的额外成本?或者如何直接处理 A 中包含的数据?
猜你喜欢
  • 2013-01-01
  • 2020-10-19
  • 2016-12-21
  • 1970-01-01
  • 2015-10-29
  • 2012-07-12
  • 2016-04-20
  • 2015-12-04
  • 2020-05-16
相关资源
最近更新 更多