首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何加速python嵌套循环?

如何加速python嵌套循环?
EN

Stack Overflow用户
提问于 2011-10-13 01:28:49
回答 2查看 1K关注 0票数 4

我试图通过计算身体两侧的重力效应来计算埋藏物体的重力效应,然后将贡献相加,得到一个站点的一个测量值,重复计算多个站点的测量值。代码如下(主体是一个正方形,代码围绕它进行顺时针计算,这就是为什么它从-x返回到-x坐标)

代码语言:javascript
运行
复制
grav = []
x=si.arange(-30.0,30.0,0.5)

#-9.79742526     9.78716693    22.32153704    27.07382349  2138.27146193
xcorn = (-9.79742526,9.78716693 ,9.78716693 ,-9.79742526,-9.79742526)
zcorn = (22.32153704,22.32153704,27.07382349,27.07382349,22.32153704)
gamma = (6.672*(10**-11))#'N m^2 / Kg^2'
rho = 2138.27146193#'Kg / m^3'
grav = []
iter_time=[]
def procedure():
    for i in si.arange(len(x)):# cycles position
        t0=time.clock()
        sum_lines = 0.0

        for n in si.arange(len(xcorn)-1):#cycles corners
            x1 = xcorn[n]-x[i]
            x2 = xcorn[n+1]-x[i]
            z1 = zcorn[n]-0.0  #just depth to corner since all observations are on the surface.
            z2 = zcorn[n+1]-0.0
            r1 = ((z1**2) + (x1**2))**0.5
            r2 = ((z2**2) + (x2**2))**0.5 
            O1 = si.arctan2(z1,x1)
            O2 = si.arctan2(z2,x2)
            denom = z2-z1
            if denom == 0.0:
                denom = 1.0e-6

            alpha = (x2-x1)/denom

            beta = ((x1*z2)-(x2*z1))/denom
            factor = (beta/(1.0+(alpha**2)))
            term1 = si.log(r2/r1)#log base 10
            term2 = alpha*(O2-O1)
            sum_lines = sum_lines + (factor*(term1-term2))
        sum_lines = sum_lines*2*gamma*rho
        grav.append(sum_lines)
        t1 = time.clock()
        dt = t1-t0
        iter_time.append(dt)

任何帮助加速这个循环的人都将不胜感激。

EN

回答 2

Stack Overflow用户

发布于 2011-10-13 02:16:49

您的xcorn和zcorn值重复,因此可以考虑缓存一些计算的结果。

看一下timeit和profile模块,以获得更多关于什么占用最多计算时间的信息。

票数 1
EN

Stack Overflow用户

发布于 2011-10-13 02:17:52

在Python循环中访问numpy数组的单个元素是非常低效的。例如,下面的Python循环:

代码语言:javascript
运行
复制
for i in xrange(0, len(a), 2):
    a[i] = i

会比以下代码慢得多:

代码语言:javascript
运行
复制
a[::2] = np.arange(0, len(a), 2)

您可以使用更好的算法(时间复杂度较低)或对numpy数组使用向量操作,如上面的示例所示。但更快的方法可能是使用Cython编译代码

代码语言:javascript
运行
复制
#cython: boundscheck=False, wraparound=False
#procedure_module.pyx
import numpy as np
cimport numpy as np

ctypedef np.float64_t dtype_t

def procedure(np.ndarray[dtype_t,ndim=1] x, 
              np.ndarray[dtype_t,ndim=1] xcorn):
    cdef:
        Py_ssize_t i, j
        dtype_t x1, x2, z1, z2, r1, r2, O1, O2 
        np.ndarray[dtype_t,ndim=1] grav = np.empty_like(x)
    for i in range(x.shape[0]):
        for j in range(xcorn.shape[0]-1):
            x1 = xcorn[j]-x[i]
            x2 = xcorn[j+1]-x[i]
            ...
        grav[i] = ...
    return grav

没有必要定义所有类型,但是如果您需要比Python更快的速度,那么至少应该定义数组和循环索引的类型。

您可以使用cProfile (Cython支持它)而不是手动调用time.clock()

调用procedure()

代码语言:javascript
运行
复制
#!/usr/bin/env python
import pyximport; pyximport.install() # pip install cython
import numpy as np

from procedure_module import procedure

x = np.arange(-30.0,30.0,0.5)
xcorn = np.array((-9.79742526,9.78716693 ,9.78716693 ,-9.79742526,-9.79742526))
grav = procedure(x, xcorn)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7744065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档