【问题标题】:Numpy array dot product - "aggregate" rows without evaluating the entire thingNumpy 数组点积 - “聚合”行而不评估整个事物
【发布时间】:2019-07-11 16:00:34
【问题描述】:

我希望计算 2d numpy 数组与其自身的内积 - 即 np.inner(A,A) - 然后为每一行提取第二个最大值及其索引:

import numpy as np
import heapq

A = np.random.rand(1000,1000)
prod = np.inner(A,A)
tmp = []
for i, x in enumerate(prod): 
    idx = heapq.nlargest(2, range(len(x)), key=x.__getitem__)[1]
    max_val = heapq.nlargest(2, x)[1]
    tmp.append((i, idx, val))

但是,如果 A 变得很大,那么在一次只需要两行的情况下,将整个产品存储在内存中是不可行的。例如,这在 C 中非常容易实现,但我不确定如何在 python 中实现。

似乎应该有一种优雅的方法来用 numpy 或 scipy 解决它,但我无法弄清楚。

【问题讨论】:

  • prod 的大小与A 相同。
  • @hpaulj 很好。我应该用 A 而不是产品来说明这一点。 IE。没有将整个 A 保存在内存中,一次只保留两行 - 在我的情况下,A 是从另一个来源产生的

标签: python numpy matrix-multiplication


【解决方案1】:

我们可以使用 np.argpartition 执行 indirect partition 并因此在那里实现一些效率 -

def nth_largest(prod): # works on prod from numpy.inner output
    idx = np.argpartition(prod,-2,axis=1)[:,-2:]
    I = np.arange(len(idx))
    idx_s = prod[I[:,None],idx].argsort(1)
    n_largest_indices = idx[I,idx_s[:,0]]
    max_vals = prod[I,n_largest_indices]
    return list(zip(I,n_largest_indices,max_vals))

如果您主要关心的是内存,请使用循环 -

def innerprod_nth_largest_loopy(A, k): # works on input A
    idxs = np.empty(len(A),dtype=np.uint64)
    vals = np.empty(len(A),dtype=A.dtype)
    for i,a in enumerate(A):
        r = a.dot(A.T)
        idx = np.argpartition(r,-k)[-k:]
        idxs[i] = idx[r[idx].argsort()[0]]
        vals[i] = r[idxs[i]]
    return list(zip(range(len(A)),idxs,vals))

但是请注意,loopy 版本会慢得多,只是在内存方面很好。

【讨论】:

  • 谢谢 - 但是这仍然需要提前计算整个“产品”,对吗?假设 A 太大以至于 A*A 根本不适合内存。而且我只需要每行中的 1 个元素(及其索引),因此存储整个内容是一种很大的浪费。
  • @SpineFeast 增加了另一个以提高内存效率。
  • 谢谢。想知道是否有一种方法可以使用一些 np 或 sp 实现两全其美 - 节省内存并提高性能?还是我应该只用 cython 写那一点?
  • @SpineFeast 我想去 cython。如果你走那条路,请告诉我们情况如何。
【解决方案2】:

我认为

prod = np.inner(A, A)

prod的第i行是

prod[i, :] = np.inner(A[i, :], A)

那么你可以使用 for 循环并且一次只计算一行的第二个最大值吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 2021-12-30
    • 2017-05-16
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 2021-04-18
    • 2019-05-12
    相关资源
    最近更新 更多