正在为下面的python脚本寻找高效的python程序

正在为下面的python脚本寻找高效的python程序,python,Python,我正在为下面的脚本寻找一个内存高效的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)

我正在为下面的脚本寻找一个内存高效的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

将你的
矩阵
(和你的
向量
)变成numpy
数组
s,而不是Python
列表
s。这将使它占用更少的内存(并且运行得更快)

要了解原因:

Python
列表是Python对象实例的列表。其中每一个都有类型信息、指针和各种各样的东西,除了8字节的数字外,还需要保留。假设每个字节都是64字节,而不是8字节。所以,每个元素64字节,乘以2500万个元素,等于16000万字节

相比之下,numpy
数组
只是原始值的列表,以及所有额外信息的单个副本(在
dtype
中)。因此,不是64*25M字节,而是8*25M+64字节,这只是大小的1/8

至于速度的提高:如果你在5000x5000矩阵上迭代,你会调用内部循环中的一些代码2500万次。如果你在做一个numpy表达式,比如
m+m
,循环中的代码是几行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

这立即消除了由于保持大约2500万Python
float
对象的开销而导致的所有内存问题,并将显著提高速度。除了不立即将整个
数组
保存在内存中之外,您无法进一步减少内存,但您应该已经很好了。(通过使用广播操作代替循环,您可以进一步提高速度,但如果内存是您的问题,并且性能良好,则可能不需要这样做。)

您的向量中没有太多的零,是吗?如果是这样,请查看scipy稀疏包…它可以为您节省很多麻烦。另外,您知道相关矩阵(必然)是对称的,因此您可以使用该事实切断一些循环。你也可以为循环去掉另一个N,因为主对角线应该都是1。问题不在于你使用了多少内存(我猜你至少有一个gig或两个RAM),而是算法(和Python)让你慢下来了。您可以使用Ben的建议来改进算法,尝试将vector设置为numpy数组,并对算法使用numpy操作以获得巨大的速度提升。此外,您的点积执行了太多的检查,例如2N^2+N,而您可以使用类似于
[check(vector[i],vector[i+1]的内容来执行N-1检查)对于范围内的i(len(向量)-1)]
。但这只是因为我很无聊,在等待脚本完成,而不是因为它会极大地改变你的执行速度。@gnibbler:如果他试图将5000x5000矩阵存储为Python
列表
,并且他有一两个内存,那么他几乎会将所有的内存都用于该矩阵。所以问题很可能是他使用了多少内存。@abarnert,你的估计有点偏差。对于32位python,每个列表有20k。20k*20k只有400MB。你能分享一个脚本吗?我不会为你写整个程序,但我会给你一些例子。