Pandas 不确定如何进一步优化(摆脱for循环)

Pandas 不确定如何进一步优化(摆脱for循环),pandas,for-loop,optimization,geopy,Pandas,For Loop,Optimization,Geopy,我正在处理几个数据集。一个数据集geodata-74观测包含印度地区名称、地区中心的纬度和经度,而另一个数据集Rainsion_2009包含地理网格中的降雨信息以及网格的纬度和经度。目的是将每个电网连接到一个地区,使电网与地区中心的距离不超过100公里。数据集很大——350000次观测。起初我试着运行两个循环,但我知道这是一种非常不和谐的方式,最后效率非常低,大约需要2.5小时。我已经设法摆脱了其中一个循环,但运行代码仍然需要1.5小时。我还有什么办法可以优化它吗 # Create empty

我正在处理几个数据集。一个数据集geodata-74观测包含印度地区名称、地区中心的纬度和经度,而另一个数据集Rainsion_2009包含地理网格中的降雨信息以及网格的纬度和经度。目的是将每个电网连接到一个地区,使电网与地区中心的距离不超过100公里。数据集很大——350000次观测。起初我试着运行两个循环,但我知道这是一种非常不和谐的方式,最后效率非常低,大约需要2.5小时。我已经设法摆脱了其中一个循环,但运行代码仍然需要1.5小时。我还有什么办法可以优化它吗

# Create empty variables for district names and distance to the centre

rainfall_2009['district'] = np.nan
rainfall_2009['distance'] = np.nan

# Make a tuple of district centre geographic location (to be used in distance geodesic command)

geodata['location'] = pd.Series([tuple(i) for i in np.array((np.array(geodata.centroid_latitude) , np.array(geodata.centroid_longitude))).T])

# Run the loop for each grid in the dataset. 

for i in tqdm(rainfall_2009.index):
    place = (rainfall_2009.latitude.iloc[i], rainfall_2009.longitude.iloc[i]) # select grid's geographic data
    distance = geodata.location.apply(lambda x: dist.geodesic(place, x).km) # construct series of distances between grid and all regional centers
    if list(distance[distance<100]) == []: # If there are no sufficiently close district centers we just continue the loop
        continue
    else:
        # We take the minimum distance to assign the closest region. 
        rainfall_2009.district.iloc[i] = geodata.distname_iaa.iloc[distance[distance < 100].idxmin()]
        rainfall_2009.distance.iloc[i] = distance[distance < 100].min()

您能直接将这些列传递到距离测地线吗?通过apply语句调用此函数可能会很慢

此示例可能会有所帮助,请参阅本文中的函数gcd_vec:

此外,是否可以执行更少的距离计算?例如,如果两个端点位于同一州或相邻州,则计算从地理栅格到区域中心的距离

更新: Numba软件包可能会进一步加快速度。您只需导入并应用装饰器。详情如下:


谢谢,成功了!我被卡住了,因为dist.geodesic只接受点作为条目,所以我使用apply,但这一个也需要数组,这使它下降到10分钟![遗憾的是,我无法执行更少的距离计算,因为我不知道哪个州的网格位于哪个州]如果你可以用精度换取速度,那么你可以使用大圆而不是测地线,参见
from numba import jit

@jit
def gcd_vec():
    # same as before