【问题标题】:fast dot product on all pair of rows所有行对上的快速点积
【发布时间】:2014-07-03 23:16:01
【问题描述】:

我有一个 2d numpy 数组 X = (xrows, xcols),我想对数组的每一行组合应用点积以获得另一个形状为 P = (xrow, xrow) 的数组。

代码如下所示:

P = np.zeros((xrow, xrow))
for i in range(xrow):
   for j in range(xrow):
      P[i, j] = numpy.dot(X[i], X[j])

如果数组X 很小但对于巨大的X 需要很多时间,则效果很好。有什么方法可以让它更快或者更 Python 化地让它更快?

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    这是通过result = X.dot(X.T)获得的

    当数组变大时,可以以块的形式完成,但根据您的 numpy 后端,这应该已经尽可能多地并行化线程。看来这就是你要找的。​​p>

    如果由于某种原因你不想依赖它,最后确实求助于多处理,你可以尝试类似

    import numpy as np
    X = np.random.randn(1000, 100000)
    block_size = 10000
    from sklearn.externals.joblib import Parallel, delayed
    products = Parallel(n_jobs=10)(delayed(np.dot)(X[:, pos:pos + block_size], X.T[pos:pos + block_size]) for pos in range(0, X.shape[1], block_size))
    product = np.sum(products, axis=0)
    

    我不认为这对相对较小的数组有用。线程有时也可以更好地处理这个问题。

    【讨论】:

    • 块大小还是 10k,总共 1k 个样本?
    • 块在特征空间中,因此 10k 块用于 100k 特征。正如我所说,我认为在大多数情况下 X.dot(X.T) 在很大程度上起到了作用。
    • `X.dot(X.T)´ 的内存消耗情况如何
    • 它应该分配np.zeros((X.shape[0],) * 2)并写入那里。绝对可以在没有太多内存开销的情况下执行此操作。不过,我不能告诉你 numpy 是如何做到的。内存对您的用例来说是个问题吗?如果有,请提供一些尺寸。
    • 您始终可以从Parallel 中提取迭代并将其作为for 循环直接保存到结果数组(上面的zeros)中,并避免将所有中间矩阵放在内存中。
    【解决方案2】:

    这在我的机器上快了 10%,因为它避免了循环:

    numpy.matrix(X) * numpy.matrix(X.T)
    

    但仍有 50% 的冗余。

    【讨论】:

    • 人们通常避免使用numpy.matrix,而更喜欢numpy.dot。否则我同意这一点,因为我提出了基本相同的建议;)
    猜你喜欢
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多