在Python中乘以非常大的2D数组

时间:2014-06-30 13:01:31

标签: python arrays performance numpy matrix

我必须在Python中将非常大的2D数组相乘大约100倍。每个矩阵由32000x32000个元素组成。

我使用np.dot(X,Y),但每次乘法需要很长时间...在我的代码实例下面:

import numpy as np

X = None
for i in range(100)
    multiplying = True
    if X == None:
        X = generate_large_2darray()
        multiplying = False
    else:
        Y = generate_large_2darray()

    if multiplying:
        X = np.dot(X, Y)

还有其他方法更快吗?

更新

以下是显示htop界面的屏幕截图。我的python脚本只使用一个核心。此外,在3h25m之后,仅进行了4次乘法。

enter image description here

更新2

我试图执行:

import numpy.distutils.system_info as info
info.get_info('atlas')

但我收到了:

/home/francescof/.local/lib/python2.7/site-packages/numpy/distutils/system_info.py:564: UserWarning: Specified path /home/apy/atlas/lib is invalid. warnings.warn('Specified path %s is invalid.' % d) {}

所以,我认为它没有很好的配置。

反之亦然,关于blas我刚收到{},没有任何警告或错误。

2 个答案:

答案 0 :(得分:2)

正如 ali_m 所建议的那样,使用BLAS库可以加快操作速度。但是,我的系统中的问题是numpy的错误配置。这是解决方案:

1)确保拥有所有必需的库(您可以使用ATLAS,OpenBLAS等)。自从我在Ubuntu中直接支持以来,我选择了ATLAS。

sudo apt-get install libatlas3gf-base libatlas-base-dev libatlas-dev

2)删除任何先前的numpy安装,例如pypm uninstall numpy(如果您使用ActivePython安装它)

3)使用pip再次安装numpy:pip install numpy

4)确保您的地图集正确链接:

import numpy.distutils.system_info as info
info.get_info('atlas')

ATLAS version 3.8.4 built by buildd on Sat Sep 10 23:12:12 UTC 2011:
   UNAME    : Linux crested 2.6.24-29-server #1 SMP Wed Aug 10 15:58:57 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
   INSTFLG  : -1 0 -a 1
   ARCHDEFS : -DATL_OS_Linux -DATL_ARCH_HAMMER -DATL_CPUMHZ=1993 -DATL_USE64BITS -DATL_GAS_x8664
   F2CDEFS  : -DAdd_ -DF77_INTEGER=int -DStringSunStyle
   CACHEEDGE: 393216
   F77      : gfortran, version GNU Fortran (Ubuntu/Linaro 4.6.1-9ubuntu2) 4.6.1
   F77FLAGS : -fomit-frame-pointer -mfpmath=387 -O2 -falign-loops=4 -Wa,--noexecstack -fPIC -m64
   SMC      : gcc, version gcc (Ubuntu/Linaro 4.6.1-9ubuntu2) 4.6.1
   SMCFLAGS : -fomit-frame-pointer -mfpmath=387 -O2 -falign-loops=4 -Wa,--noexecstack -fPIC -m64
   SKC      : gcc, version gcc (Ubuntu/Linaro 4.6.1-9ubuntu2) 4.6.1
   SKCFLAGS : -fomit-frame-pointer -mfpmath=387 -O2 -falign-loops=4 -Wa,--noexecstack -fPIC -m64
{'libraries': ['lapack', 'f77blas', 'cblas', 'atlas'], 'library_dirs': ['/usr/lib/atlas-base/atlas', '/usr/lib/atlas-base'], 'define_macros': [('ATLAS_INFO', '"\\"3.8.4\\""')], 'language': 'f77', 'include_dirs': ['/usr/include/atlas']}

答案 1 :(得分:1)

矩阵乘法总是很昂贵,特别是在O(n3)附近。在Numpy中执行此操作可能是处理它的最快方法,而不是在编译程序中编写自己的矩阵乘法器,该程序更接近金属" (比如C)......这可能还会慢一些。我认为你是以最好的方式进行这项操作,但是你必须意识到32000x32000矩阵非常大,无法进行任何操作,更不用说矩阵乘法了。

这是坏消息,但这是好消息。我不知道您正在使用哪种类型的数据,但可能存在且通常是所讨论的矩阵的对称性,这可以大大简化计算。如果您的数据不是完全随机的,那么可能会有希望,但您必须查看您正在使用的矩阵的实际结构。我建议阅读一些"特殊矩阵"查看您的数据是否属于这些类别之一。您在数据类别中找到的任何信息也应该讨论或引用有效的算法来管理昂贵的操作。