我正在寻找以下脚本的内存高效python脚本。以下脚本适用于较小的尺寸,但在我的实际计算中矩阵的尺寸为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
答案 0 :(得分:1)
将您的matrix
(和您的vector
)变为numpy array
而不是Python list
。这将使它占用更少的内存(并且运行得更快)。
理解原因:
Python list
是Python对象实例的列表。这些中的每一个都有类型信息,指针和各种其他东西,以保持超出8字节的数字。假设每个结果都是64个字节而不是8个。因此,每个元素为64个字节,乘以25M个元素,等于1600M字节!
相比之下,numpy array
只是原始值的列表,以及所有额外信息的单个副本(在dtype
中)。因此,不是64 * 25M字节,而是8 * 25M + 64字节,这只是大小的1/8。
至于速度增加:如果你遍历5000x5000矩阵,你在内循环中调用一些代码25M次。如果你正在做一个像m + m
这样的numpy表达式,那么循环中的代码就是几行C代码,它们被编译成几十个机器代码操作,这非常快。如果你在Python中显式地进行循环,那么循环内部必须每次通过循环驱动Python解释器,这要慢得多。 (最重要的是,C编译器将优化代码,numpy也可能有一些明确的优化。)根据循环内部工作的微不足道,加速可以是2x到10000x之间的任何值。所以,即使你必须让事情有点复杂,试着找到一种方法来表达每个步骤作为一个数组广播而不是一个循环,它会更快。
那么,你是怎么做到的?简单。而不是:
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
一次保留在内存中之外,你不能再进一步减少内存,但你应该没事。 (您可以通过使用广播操作代替循环来提高速度,但如果内存是您的问题,并且性能良好,则可能没有必要。)