如何在python中加速for循环

2024-09-30 19:27:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在处理两组三个相同大小的大列表,其中包含UTM格式的经度、纬度和高度坐标(见下面的列表)。数组包含重叠的坐标(即经度和纬度值相等)。如果Lon中的值等于Lon2,Lat中的值等于Lat2,那么我要计算这些指标的平均高度。但是,如果它们不相等,那么经度、纬度和高度值将保持不变。我只想将重叠的数据替换为一组经纬度坐标,并计算这些坐标的平均值。你知道吗

这是我目前为止的尝试

 import numpy as np

 Lon = [450000.50,459000.50,460000,470000]
 Lat = [5800000.50,459000.50,500000,470000]
 Alt = [-1,-9,-2,1]
 Lon2 = [450000.50,459000.50,460000,470000]
 Lat2 = [5800000.50,459000.50,800000,470000]
 Alt2= [-3,-1,-20,2]

 MeanAlt = []
 appendAlt = MeanAlt.append
 LonOverlap = []
 appendLon = LonOverlap.append
 LatOverlap = []
 appendLat = LatOverlap.append

 for i, a in enumerate(Lon and Lat and Alt):
     for j, b in enumerate(Lon2 and Lat2 and Alt2):
         if Lon[i]==Lon2[j] and Lat[i]==Lat2[j]:
             MeanAltData = (Alt[i]+Alt2[j])/2
             appendAlt(MeanAltData)
             LonOverlapData = Lon[i]
             appendLat(LonOverlapData)
             LatOverlapData = Lat[i]
             appendLon(LatOverlapData)

 print(MeanAlt) # correct ans should be MeanAlt = [-2.0,-5,1.5]
 print(LonOverlap)
 print(LatOverlap)

我在一个jupyter笔记本电脑里工作,我的笔记本电脑速度很慢,所以我需要让这个代码更有效率。如果能帮上忙,我将不胜感激。谢谢:)


Tags: and高度altlonprintlatappend纬度
3条回答

我相信您的代码可以通过两种方式得到改进:

  • 首先,使用tuples而不是lists,因为迭代元组比迭代列表generally faster。你知道吗
  • 其次,您的for循环可以简化为只有一个循环,它迭代您要读取的元组的索引。当然,这个假设适用于当且仅当所有元组包含相同数量的项(即:len(Lat) == len(Lon) == len(Alt) == len(Lat2) == len(Lon2) == len(Alt2))。你知道吗

下面是改进的代码(我冒昧地删除了import numpy语句,因为它没有在您提供的代码中使用):

# use of tuples
Lon = (450000.50, 459000.50, 460000, 470000)
Lat = (5800000.50, 459000.50, 500000, 470000)
Alt = (-1, -9, -2, 1)
Lon2 = (40000.50, 459000.50, 460000, 470000)
Lat2 = (5800000.50, 459000.50, 800000, 470000)
Alt2 = (-3, -1, -20, 2)

MeanAlt = []
appendAlt = MeanAlt.append
LonOverlap = []
appendLon = LonOverlap.append
LatOverlap = []
appendLat = LatOverlap.append

# only one loop
for i in range(len(Lon)):
    if (Lon[i] == Lon2[i]) and (Lat[i] == Lat2[i]):
        MeanAltData = (Alt[i] + Alt2[i]) / 2
        appendAlt(MeanAltData)
        LonOverlapData = Lon[i]
        appendLat(LonOverlapData)
        LatOverlapData = Lat[i]
        appendLon(LatOverlapData)

print(MeanAlt)  # correct ans should be MeanAlt = [-2.0,-5,1.5]
print(LonOverlap)
print(LatOverlap)

我在笔记本电脑上执行了这个程序一百万次。按照我的代码,所有执行所需的时间是:1.41秒。另一方面,使用你的方法所需的时间是:4.01秒。你知道吗

这不是100%的功能等效,但我猜它更接近您实际需要的:

Lon = [450000.50,459000.50,460000,470000]
Lat = [5800000.50,459000.50,500000,470000]
Alt = [-1,-9,-2,1]
Lon2 = [40000.50,459000.50,460000,470000]
Lat2 = [5800000.50,459000.50,800000,470000]
Alt2= [-3,-1,-20,2]

MeanAlt = []
appendAlt = MeanAlt.append
LonOverlap = []
appendLon = LonOverlap.append
LatOverlap = []
appendLat = LatOverlap.append

ll = dict((str(la)+'/'+str(lo), al) for (la, lo, al) in zip(Lat, Lon, Alt))

for la, lo, al in zip(Lon2, Lat2, Alt2):
    al2 = ll.get(str(la)+'/'+str(lo))
    if al2:
        MeanAltData = (al+al2)/2
        appendAlt(MeanAltData)
        LonOverlapData = lo
        appendLat(LonOverlapData)
        LatOverlapData = la
        appendLon(LatOverlapData)

print(MeanAlt) # correct ans should be MeanAlt = [-2.0,-5,1.5]
print(LonOverlap)
print(LatOverlap)

或更简单:

Lon = [450000.50,459000.50,460000,470000]
Lat = [5800000.50,459000.50,500000,470000]
Alt = [-1,-9,-2,1]

Lon2 = [40000.50,459000.50,460000,470000]
Lat2 = [5800000.50,459000.50,800000,470000]
Alt2= [-3,-1,-20,2]

ll = dict((str(la)+'/'+str(lo), al) for (la, lo, al) in zip(Lat, Lon, Alt))

result = []
for la, lo, al in zip(Lon2, Lat2, Alt2):
    al2 = ll.get(str(la)+'/'+str(lo))
    if al2:
        result.append((la, lo, (al+al2)/2))

print(result)

在实践中,我会尝试从更好的结构化输入数据开始,使得转换为dict,或者至少是“zip()”是不必要的。你知道吗

使用numpy将计算矢量化。对于1000000个长数组,如果输入已经是numpy.ndarray,那么执行时间应该是15-25ms微秒,如果输入是Python列表,那么执行时间应该是140ms。你知道吗

import numpy as np
def mean_alt(lon, lon2, lat, lat2, alt, alt2):
    lon = np.asarray(lon)
    lon2 = np.asarray(lon2)
    lat = np.asarray(lat)
    lat2 = np.asarray(lat2)
    alt = np.asarray(alt)
    alt2 = np.asarray(alt2)
    ind = np.where((lon == lon2) & (lat == lat2))
    mean_alt = (0.5 * (alt[ind] + alt2[ind])).tolist()
    return (lon[ind].tolist(), lat[ind].tolist(), mean_alt)

相关问题 更多 >