要在磁盘上存储大矩阵,我使用numpy.memmap。
以下是测试大矩阵乘法的示例代码:
import numpy as np
import time
rows= 10000 # it can be large for example 1kk
cols= 1000
#create some data in memory
data = np.arange(rows*cols, dtype='float32')
data.resize((rows,cols))
#create file on disk
fp0 = np.memmap('C:/data_0', dtype='float32', mode='w+', shape=(rows,cols))
fp1 = np.memmap('C:/data_1', dtype='float32', mode='w+', shape=(rows,cols))
fp0[:]=data[:]
fp1[:]=data[:]
#matrix transpose test
tr = np.memmap('C:/data_tr', dtype='float32', mode='w+', shape=(cols,rows))
tr= np.transpose(fp1) #memory consumption?
print fp1.shape
print tr.shape
res = np.memmap('C:/data_res', dtype='float32', mode='w+', shape=(rows,rows))
t0 = time.time()
# redifinition ? res= np.dot(fp0,tr) #takes 342 seconds on my machine, if I multiplicate matrices in RAM it takes 345 seconds (I thinks it's a strange result)
res[:]= np.dot(fp0,tr) # assignment ?
print res.shape
print (time.time() - t0)
所以我的问题是:
此外,我对解决内存使用受限的线性方程组(SVD和其他)的算法感兴趣。 也许这种算法称为核外或迭代,我认为有一些类比,如硬盘< - > ram,gpu ram< - > cpu ram,cpu ram< - > cpu cache。
同样here我在PyTables中发现了一些关于矩阵乘法的信息。
我也在R中找到this但我需要它用于Python或Matlab。
答案 0 :(得分:5)
Dask.array使用阻塞算法和任务调度为大型磁盘阵列提供了一个numpy接口。它可以很容易地进行核外矩阵乘法和其他简单的numpy操作。
阻塞的线性代数更难,你可能想看看关于这个主题的一些学术着作。 Dask确实支持高和瘦的矩阵上的QR和SVD分解。
无论是大型数组,你真的想要阻塞算法,而不是天真的遍历会以不愉快的方式击中磁盘。
答案 1 :(得分:1)
考虑使用 NumExpr 进行处理:https://github.com/pydata/numexpr
...在内部,NumExpr采用自己的矢量化虚拟机,该虚拟机是围绕分块读取策略设计的,以便有效地在内存中的最佳大小的数据块上运行。如果调整得当,它可以轻松击败天真的NumPy操作。
NumExpr可能会在您的问题细分中涵盖#2。如果使用可流式二进制格式解决#1问题,则可以在加载数据文件时使用分块读取方法 - 如下所示:
with open('path/to/your-data.bin', 'rb') as binary:
while True:
chunk = binary.read(4096) # or what have you
if not chunk:
break
如果这对您来说太低级,我建议您查看 HDF5 库并格式化:http://www.h5py.org - 这是基于NumPy的二进制序列化的最佳解决方案我所知道的结构。 h5py
模块支持压缩,分块读取,dtypes,元数据...您可以命名。