【问题标题】:Improving run time with Python data structure使用 Python 数据结构提高运行时间
【发布时间】:2017-05-03 12:37:13
【问题描述】:

我想改进我的代码的运行时间。它目前非常慢,因为我以附加模式打开一个文本文件并将值写入文件末尾,然后每次循环时关闭文件。有人可以帮我将所有数据存储在 python 数据结构中,然后以相同的格式输出结果(即文本文件中的所有结果,每个值用空格分隔)?我是 python 新手,并不真正了解如何实现这一点。这是我的代码:

######import required packages########
import numpy 
import math

#######Set working directory##########
import os 
os.chdir('/Users/DevEnv/')

######Remove files generated from previous simulations##### 
try:
    os.remove('excitations.txt')
except OSError:
    pass

##############Set Model Parameters#####################
n=2 #number of iterations -Change for desired number of loops

tlength=1501 #Length of time interval - DO NOT CHANGE

wu=100 #DO NOT CHANGE

N=250 #wu*T/4Pi approximately - DO NOT CHANGE

Pi=math.radians(180)
t=numpy.linspace(0,10,tlength)
Dw=wu/float(N)


for k in range(0,n):

    A=[]

    wi=[]
    for i in range (0,N):
        wi.append(Dw/2+i*Dw) #Middle of distribution
    for j in range (0,tlength):
        Aj=[]
        phi=numpy.random.rand(N,1)*2*Pi #Generate random phase angle on 0,2pi
        for i in range (0,N):
            w=wi[i]
            Sv=(((1+4*0.6**2*(w/15)**2)/((1-(w/15)**2)**2+4*0.6**2*(w/15)**2))*(0.0000753*(w/1.5)**4/((1-(w/1.5)**2)**2+4*0.6**2*(w/1.5)**2)))
            Aj.append(math.sqrt(Sv*Dw)*2*math.cos(wi[i]*t[j]+phi[i]))
        A.append(sum(Aj))
    outFile = open('excitations.txt','a') #open/create the output file
    for item in A:
        outFile.write('%s ' %item)
    outFile.write('\n')
    outFile.close() #close the output file

【问题讨论】:

  • 首先你可以存储不变的计算结果。例如- 4*0.6**2。其次,您有三个嵌套循环,这通常很糟糕。检查你是否真的需要三个?
  • 感谢您的建议。我将常量值存储为变量。但是,我确实需要三个嵌套循环

标签: python loops runtime


【解决方案1】:

代码中的大部分时间都被余弦计算占用(不是由于写入文件)。使用time 测量代码的不同部分所花费的时间,如here 所述。

您可以通过转换为numpy array operations 来获得显着的改进(快约 10 倍),如下所示(未经测试,请在使用前检查)

for k in range(0,n):

    A=[]

    wi=[]
    for i in range (0,N):
        wi.append(Dw/2+i*Dw) #Middle of distribution

    # convert wi to numpy array as that allows array operations
    wi_np = numpy.array(wi) 

    # Sv calculation does not change with j so moving it outside the loop
    # also instead of looping over i to calculate each element
    # use numpy's array operations over wi_np
    p1 = (wi_np / 15)**2
    p2 = p1 * 100 # => (wi_np / 1.5) ** 2
    arg1 = (1 + 4 * 0.6**2 * p1) / ((1 - p1)**2 + 4 * 0.6**2 * p1)
    arg2 = 0.0000753 * p2**2 / ((1 - p2)**2 + 4 * 0.6**2 * p2) 
    Sv_np = arg1 * arg2

    # amp is an array of size N
    amp =  numpy.sqrt(Sv_np * Dw) 

    for j in range (0,tlength):
        # changing the dimensions from (N, 1) to N
        # so that phi is an array of scalars
        # otherwise it messes up the array operations
        phi = numpy.random.rand(N) * 2 * Pi 

        # angle is an array of size N
        angle = wi_np * t[j] + phi 

        # numpy cos is faster than math.cos
        # the multiplication operator between numpy arrays is element wise 
        # hence Aj_np is also array of size N
        Aj_np = 2 * amp * numpy.cos(angle)
        A.append(sum(Aj_np))

    outFile = open('excitations.txt','a') #open/create the output file
    for item in A:
       outFile.write('%s ' %item)
    outFile.write('\n')
    outFile.close() #close the output file

【讨论】:

  • 太好了,这对您有很大帮助!非常感谢:)
猜你喜欢
  • 1970-01-01
  • 2017-01-27
  • 1970-01-01
  • 1970-01-01
  • 2016-01-18
  • 2016-09-15
  • 2019-04-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多