【问题标题】:multiplying two huge matrices using numpy.dot使用 numpy.dot 将两个巨大的矩阵相乘
【发布时间】:2016-03-08 14:43:48
【问题描述】:

我需要将两个巨大的向量 (30720,1)* (1,30720) 相乘,所以这将得到一个 30720*30720 矩阵。我正在使用 numpy.dot 将它们相乘,但这需要很长时间。

【问题讨论】:

  • 这和 C++ 有什么关系?而且一个 30kx30k 的矩阵是巨大的,当然需要很长时间来计算。
  • 当然这个乘法需要时间。并且专门优化的低级例程通常比像 numpy 这样的通用工具更有效(即使 numpy 已经擅长这种操作操作)。话虽如此,对于 SO 网站来说,任何严肃的答案都可能太长了,所以这个问题对我来说看起来太宽泛了。
  • Numpy 使用像 BLAS 这样的库来进行这种计算。但是内存交换可能会占用时间。

标签: python numpy matrix


【解决方案1】:

使用float64 数据,结果大小约为 7 Go,因此不适合大量 PC RAM。但是你只有 30720² # 1e9 乘法要做,这需要几秒钟。

避免内存问题的一种方法是将结果切成合理的块,大小

n=3
div=10240
a=rand(n*div,1)
b=rand(1,n*div)
import pickle

def calculate(i,j):
    u=dot(a[i*div:(i+1)*div,:],b[:,j*div:(j+1)*div])
    return u

def save(i,j,u):
     with open('data'+str(i)+str(j)+'.pk','wb') as f :
                   pickle.dump(u,f)

def timecount(f,args):
   t0=time.time()
   res=f(*args)
   return res,time.time()-t0

def multidot():
  tcalc,tsave=0,0  
  for i in range(n):
    for j in range(n):
        print (i,j)
        u,dt=timecount(calculate,(i,j))
        tcalc+=dt
        _,dt=timecount(save,(i,j,u))
        tsave+=dt
  print('dot time',tcalc)
  print('save time',tsave)

然后运行:

In [64]: multidot()
 0 0
 0 1
 0 2
 1 0
 1 1
 1 2
 2 0
 2 1
 2 2
dot time 4.697121858596802
save time 29.11250686645508

所以dot 没有问题,只是内存问题。

要读回你的数据,逐块读取,就像这样:

with open('data00.pk','rb') as f : u=pickle.load(f)

运行后别忘了del data*.pk,它需要 6Go 在你的磁盘上;)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多