Python:如何优化此代码

Python:如何优化此代码,python,performance,numpy,Python,Performance,Numpy,我试图优化下面的代码,但我不知道如何提高计算速度。下面的代码运行大约需要30秒。这需要时间,因为bootsam和filedata矩阵。有人能帮我优化这个代码吗 有可能提高性能吗 import numpy as np filedata=np.genfromtxt('monthlydata1970to2010.txt',dtype='str') # this will creae 980 * 7 matrix nboot=5000 results=np.zeros((11,nboot));

我试图优化下面的代码,但我不知道如何提高计算速度。下面的代码运行大约需要30秒。这需要时间,因为bootsam和filedata矩阵。有人能帮我优化这个代码吗 有可能提高性能吗

import numpy as np
filedata=np.genfromtxt('monthlydata1970to2010.txt',dtype='str') # this will creae 980 * 7 matrix
nboot=5000  
results=np.zeros((11,nboot));   #this will create 11*5000 matrix  
results[0,:]=600  
horizon=360  
balance=200  
bootsam=np.random.randint(984, size=(984, nboot)) # this will create 984*5000 matrix
for bs in range(0,nboot):  
   for mn in range(1,horizon+1):  
        if mn%12 ==1:  
            bondbal = 24*balance  
            sp500bal=34*balance  
            russbal = 44*balance  
            eafebal=55*balance  
            cashbal =66*balance  
            bondbal=bondbal*(1+float(filedata[bootsam[mn-1,bs]-1,2]))  
            sp500bal=sp500bal*(1+float(filedata[bootsam[mn-1,bs]-1,3]))  
            russbal=russbal*(1+float(filedata[bootsam[mn-1,bs]-1,4]))  
            eafebal=eafebal*(1+float(filedata[bootsam[mn-1,bs]-1,5]))  
            cashbal=cashbal*(1+float(filedata[bootsam[mn-1,bs]-1,6]))  
            balance=bondbal + sp500bal + russbal + eafebal + cashbal  
        else:  
            bondbal=bondbal*(1+float(filedata[bootsam[mn-1,bs]-1,2]))
            sp500bal=sp500bal*(1+float(filedata[bootsam[mn-1,bs]-1,3]))
            russbal=russbal*(1+float(filedata[bootsam[mn-1,bs]-1,4]))
            eafebal=eafebal*(1+float(filedata[bootsam[mn-1,bs]-1,5]))
            cashbal=cashbal*(1+float(filedata[bootsam[mn-1,bs]-1,6]))
            balance=bondbal + sp500bal + russbal + eafebal + cashbal
            if mn == 60:
               results[1,bs]=balance
            if mn == 120: 
               results[2,bs]=balance
            if mn == 180:
               results[3,bs]=balance
            if mn == 240:
               results[4,bs]=balance
            if mn == 300: 
               results[5,bs]=balance  
基本代数:执行x=x*1.23 360次可以很容易地转换为一次执行

x=x*1.23**360


重构你的代码,你会发现实际上并不需要循环。

如果没有看到真正的代码,很难回答。我无法让您的示例工作,因为balance在代码的早期被设置为inf,正如在问题的注释中所注意到的那样。无论如何,一个非常明显的优化不是在每次迭代中读取bootsam[mn-1,bs]元素五次以计算xxbal变量。所有这些变量都使用相同的bootsam元素,因此您应该读取该元素一次并重用它:

for bs in xrange(0,nboot):
   for mn in xrange(1,horizon+1):
        row = bootsam[mn-1,bs]-1
        if (mn % 12) == 1:  
            bondbal = 24*balance
            sp500bal=34*balance
            russbal = 44*balance
            eafebal=55*balance
            cashbal =66*balance

            bondbal=bondbal*(1+float(filedata[row,2]))  
            sp500bal=sp500bal*(1+float(filedata[row,3]))  
            russbal=russbal*(1+float(filedata[row,4]))  
            eafebal=eafebal*(1+float(filedata[row,5]))  
            cashbal=cashbal*(1+float(filedata[row,6]))  
            balance=bondbal + sp500bal + russbal + eafebal + cashbal
        else:  
            bondbal=bondbal*(1+float(filedata[row,2]))  
            sp500bal=sp500bal*(1+float(filedata[row,3]))  
            russbal=russbal*(1+float(filedata[row,4]))  
            eafebal=eafebal*(1+float(filedata[row,5]))  
            cashbal=cashbal*(1+float(filedata[row,6]))  
优化后的代码使用了一个假的平衡值,运行速度比我的旧Acer Aspire上的原始代码快近两倍

更新

如果需要进一步优化,您至少可以再做两件事:

不要在filedata的每个访问元素上添加1并转换为float。而是在创建时将1添加到数组中,并给它一个float数据类型。 不要使用混合numpy和内置数字的算术表达式,因为Python算术运算速度较慢。您可以在 以下代码遵循这些建议:

filedata=np.genfromtxt('monthlydata1970to2010.txt',dtype='str') # this will creae 980 * 7 matrix
my_list = (np.float(1) + filedata.astype(np.float)).tolist() # np.float is converted to Python float
nboot=5000
results=np.zeros((11,nboot))   #this will create 11*5000 matrix
results[0,:]=600  
horizon=360
balance=200
bootsam=np.random.randint(5, size=(984, nboot)) # this will create 984*5000 matrix
for bs in xrange(0,nboot):
   for mn in xrange(1,horizon+1):
        row = int(bootsam[mn-1,bs]-1)
        if (mn % 12) == 1:
            bondbal = 24*balance
            sp500bal=34*balance
            russbal = 44*balance
            eafebal=55*balance
            cashbal =66*balance

            bondbal=bondbal*(my_list[row][2])  
            sp500bal=sp500bal*(my_list[row][3])  
            russbal=russbal*(my_list[row][4])  
            eafebal=eafebal*(my_list[row][5])  
            cashbal=cashbal*(my_list[row][6])  
            balance=bondbal + sp500bal + russbal + eafebal + cashbal
        else:  
            bondbal=bondbal*(my_list[row][2])  
            sp500bal=sp500bal*(my_list[row][3])  
            russbal=russbal*(my_list[row][4])  
            eafebal=eafebal*(my_list[row][5])  
            cashbal=cashbal*(my_list[row][6])  
            balance=bondbal + sp500bal + russbal + eafebal + cashbal  

通过这些更改,代码的运行速度几乎是以前优化的代码的两倍。

1+float100与101是一样的。如果您说出您试图对代码执行的操作,而不是询问如何改进代码,则可能会有所帮助。如果您想检查代码所用的时间,请使用timeit模块,而timeit是计时的最佳方式有些东西,如果你用datetime得到的时间是7秒。现在,timeit可能会说同样的话。@HunterMcMillen:基本上我是在把一些matlab代码转换成python,我不能写实际的代码,因为这是保密的,这里的1+float100来自二维字符串矩阵,这就是我编写float来转换字符串变量的原因。感谢您查看代码。你的评论真的节省了我的时间。现在我已经替换了行中的变量,并且能够在15秒内执行代码。而不是30秒。我已经在我的本地机器上运行了代码,并且我能够执行此代码。你能进一步优化这个代码吗?你太棒了。谢谢,我们从28秒开始。现在达到4秒。再次感谢。