简体   繁体   中英

Numpy dot product of very large arrays

I have a problem of very slow running code. A try to calculate the dot product of a very large binary matrix (170544 X 22) by its transpose. First I tried this code

import numpy as np
start = time.time()
import warnings
warnings.filterwarnings("ignore", message='genfromtxt',     category=UserWarning)
np.set_printoptions(threshold=np.nan)

fin = open('E:/myscripts/Abin.txt', 'rb')    # input file (170544X22     binary matrix)
fin1 = open('E:/myscripts/AbinT.txt', 'rb')    # input file (22X170544        binary matrix the transpose of Abin)
fout = open('E:/myscripts/RPartial.txt', 'w+b')  # output file

FW = np.genfromtxt(fin,delimiter=',',   dtype=int)
WF = np.genfromtxt(fin1,delimiter=',',   dtype=int)

r = np.dot(FW,WF) #r calculation
np.savetxt(fout, r,  fmt='%i' ,delimiter=',', newline='\r\n')

fin.close()
fin1.close()
fout.close() 

but there was a memory error. Then I changed the r calculation using a row approach:

for row in FW:
    a=FW[row,:]
    r = np.dot(a,WF)
    np.savetxt(fout, r,  fmt='%i' ,delimiter=',', newline='\r\n')

The code now works, but its is very slow, after 90 min only 8000 rows was calculated. The hardware is a I7 with 12GB of ram, running windows 64 bits. How a can speed up the code?

The data is like this

([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0],
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,0,0,0])

and the result should be like

([15,14,14,14,14],
 [14,15,14,14,14],
 [14,14,15,14,14],
 [14,14,14,15,14],
 [14,14,14,14,15]) .

This sounds like a sparse matrix problem for which scipy provides a package . These are matrices with many 0 elements (like in your example). Operations will take the sparseness into account and the matrix will take up less space in memory. Remember to do matrix operations like FW.dot(WF) (use this rather than np.dot ).

As I have written in the comments the output array will be 232GB in size(int64). If you wan't to store the results to disk using h5py for this task would be a proper solution.

A summation about first axis simplifies the problem a bit. If you wan't the pure dot product I can update my answer. But this will be a bit more complicated and slower.

res=np.zeros(WF.shape[1])
for i in range(WF.shape[1]):
  a=np.copy(WF[:,i])
  r=np.dot(FW,a)
  res[i] = np.sum(r)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM