Python NUMPY HUGE 矩阵乘法

标签 python performance numpy matrix-multiplication

我需要将两个大矩阵相乘并对它们的列进行排序。

 import numpy
 a= numpy.random.rand(1000000, 100)
 b= numpy.random.rand(300000,100)
 c= numpy.dot(b,a.T)
 sorted = [argsort(j)[:10] for j in c.T]

此过程需要大量时间和内存。有没有办法加快这个过程?如果不是,我如何计算执行此操作所需的 RAM?我目前有一个带有 4GB RAM 且没有交换空间的 EC2 盒子。

我想知道这个操作是否可以序列化,我不必将所有内容都存储在内存中。

最佳答案

为了加快速度,您可以做的一件事是使用优化的 BLAS 库编译 numpy,例如ATLAS、GOTO blas 或英特尔专有的 MKL。

要计算所需的内存,您需要监控 Python 的驻留集大小(“RSS”)。以下命令在 UNIX 系统(准确地说是 FreeBSD,在 64 位机器上)上运行。

> ipython

In [1]: import numpy as np

In [2]: a = np.random.rand(1000, 1000)

In [3]: a.dtype
Out[3]: dtype('float64')

In [4]: del(a)

为了获取我运行的 RSS:

ps -xao comm,rss | grep python

[编辑:请参阅 ps manual page有关选项的完整说明,但基本上这些 ps 选项使其仅显示所有进程的命令和驻留集大小。我相信 Linux 的 ps 的等效格式是 ps -xao c,r。]

结果是;

  • 启动解释器后:24880 kiB
  • 导入 numpy 后:34364 kiB
  • 创建a后:42200 kiB
  • 删除a后:34368 kiB

计算尺寸;

In [4]: (42200 - 34364) * 1024
Out[4]: 8024064

In [5]: 8024064/(1000*1000)
Out[5]: 8.024064

如您所见,计算出的大小与默认数据类型 float64 的 8 个字节非常匹配。区别在于内部开销。

以 MiB 为单位的原始数组大小约为;

In [11]: 8*1000000*100/1024**2
Out[11]: 762.939453125

In [12]: 8*300000*100/1024**2
Out[12]: 228.8818359375

这还不算太糟糕。但是,点积会太大:

In [19]: 8*1000000*300000/1024**3
Out[19]: 2235.1741790771484

那是 2235 GiB!

你可以做的是将问题拆分,然后将 dot 操作分成几部分来执行;

  • 加载 b 作为 ndarray
  • a 中的每一行依次加载为 ndarray
  • 将行乘以 b 的每一列并将结果写入文件。
  • del() 该行并加载下一行。

这不会让它变得更快,但它会使用更少的内存!

编辑: 在这种情况下,我建议以二进制格式编写输出文件(例如使用 structndarray.tofile)。这将使从文件中读取列变得更加容易,例如一个 numpy.memmap

关于Python NUMPY HUGE 矩阵乘法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25046076/

相关文章:

使用 aiohttp 的 Python lib 美丽的汤

python - 替换n维numpy数组中特定轴索引的元素

python - builtwith: import SyntaxError 即使在添加了 Python 3 支持之后?

python - Pandas to_datetime 意外更改年份

css - 何时下载样式表中的背景图像?

c - C 和 Fortran 中指针在确定程序速度方面的作用

sql - 将两部分 SQL 查询组合成一个查询

python - 将 pandas groupby() 中的值提取到结合单个值和 numpy 数组的新数据集中

python - 使用 SciPy 对 3d 数据进行插值时如何提高性能

python - 如何从 numpy.ndarray 中提取值