Python:如何优化此代码
我试图优化下面的代码,但我不知道如何提高计算速度。下面的代码运行大约需要30秒。这需要时间,因为bootsam和filedata矩阵。有人能帮我优化这个代码吗 有可能提高性能吗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));
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秒。再次感谢。