使用numpy.dot乘以两个巨大的矩阵

时间:2016-03-08 14:43:48

标签: python numpy matrix

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

1 个答案:

答案 0 :(得分:1)

带有float64数据的

,结果大小约为7 Go,因此它不适合很多PC RAM。但是你只需要30720²#1e9乘法,这需要几秒钟。

避免内存问题的一种方法是将结果以合理的块切割,大小<1。 1Go,并将部分结果保存为具有二进制协议的文件以提高速度,并添加控制以发生的事情:

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;)