Numpy高效大矩阵乘法

时间:2013-10-14 11:18:47

标签: python numpy matrix bigdata pytables

要在磁盘上存储大矩阵,我使用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)

所以我的问题是:

  1. 如何将使用此过程的应用程序的内存消耗限制为某些值,例如100Mb(或1Gb或其他)。还有我不明白如何估计程序的内存消耗(我认为内存只分配什么时候创建“data”变量,但是当我们使用memmap文件时使用了多少内存?)
  2. 也许存在一些存储在磁盘上的大矩阵乘法的最优解?例如,数据可能没有最佳地存储在磁盘上或者是从磁盘中获取,没有正确处理,而且dot产品只使用一个核心。也许我应该使用像PyTables这样的东西?
  3. 此外,我对解决内存使用受限的线性方程组(SVD和其他)的算法感兴趣。 也许这种算法称为核外或迭代,我认为有一些类比,如硬盘< - > ram,gpu ram< - > cpu ram,cpu ram< - > cpu cache。

    同样here我在PyTables中发现了一些关于矩阵乘法的信息。

    我也在R中找到this但我需要它用于Python或Matlab。

2 个答案:

答案 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,元数据...您可以命名。

祝你好运!