-1

我正在为以下脚本寻找内存高效的 p​​ython 脚本。以下脚本适用于较小的尺寸,但在我的实际计算中矩阵的尺寸为 5000X5000。因此,完成它需要很长时间。谁能帮助我我该怎么做?

def check(v1,v2):
    if len(v1)!=len(v2):
        raise ValueError,"the lenght of both arrays must be the same"
    pass
def d0(v1, v2):
    check(v1, v2)
    return dot(v1, v2)
import numpy as np
from pylab import *
vector=[[0.1, .32, .2, 0.4, 0.8], [.23, .18, .56, .61, .12], [.9, .3, .6, .5, .3], [.34, .75, .91, .19, .21]]
rav= np.mean(vector,axis=0)
#print rav
#print vector
m= vector-rav
corr_matrix=[]
for i in range(0,len(vector)):
    tmp=[]
    x=sqrt(d0(m[i],m[i]))
    for j in range(0,len(vector)):
        y=sqrt(d0(m[j],m[j]))
        z=d0(m[i],m[j])
        w=z/(x*y)
        tmp.append(w)
    corr_matrix.append(tmp)
print corr_matrix
4

1 回答 1

1

将你的matrix(和你的vector)变成 numpy arrays 而不是 Python lists。这将使其占用更少的内存(并且运行速度更快)。

要了解原因:

Pythonlist是 Python 对象实例的列表。它们中的每一个都有类型信息、指针和各种其他东西,除了 8 字节数字之外还要保留。假设每个最终都是 64 字节而不是 8 字节。所以,每个元素 64 字节,乘以 25M 元素,等于 1600M 字节!

相比之下,numpyarray是一个仅包含原始值的列表,以及所有额外信息的单个副本(在dtype. 所以,不是 64 * 25M 字节,而是 8 * 25M + 64 字节,这只是大小的 1/8。

至于速度提升:如果您迭代 5000x5000 矩阵,您将在内循环中调用一些代码 25M 次。如果你正在做一个像m + m,循环内的代码是几行 C 代码,可以编译成几十个机器代码操作,速度非常快。如果您在 Python 中显式地执行循环,则该循环的内部每次都必须驱动 Python 解释器通过循环,这要慢得多。(最重要的是,C 编译器会优化代码,numpy 也可能有一些显式的优化。)根据循环内工作的琐碎程度,加速可以从 2 倍到 10000 倍不等。所以,即使你不得不让事情变得有点复杂,试着想办法把每一步表达成数组广播而不是循环,这样会快得多。


那么,你是怎么做到的呢?简单的。而不是这个:

corr_matrix=[]
for i in range(len(vector)):
    tmp=[]
    # …
    for j in range(len(vector)):
        # …
        tmp.append(w)
    corr_matrix.append(tmp)

做这个:

corr_matrix=np.zeros((len(vector), len(vector))
for i in range(len(vector)):
    # …
    for j in range(len(vector)):
        # …
        corr_matrix[i, j] = w

这立即消除了由保留大约 25M Python 对象的开销引起的所有内存问题float,并且还将显着提高速度。你不能进一步减少内存,除非你不能array一次将整个内存保存在内存中,但你应该已经没问题了。(您可以通过使用广播操作代替循环来进一步提高速度,但如果内存是您的问题,并且性能很好,则可能没有必要。)

于 2013-02-06T02:01:20.653 回答