我有一个大型数据框,其中包含来自世界各地各种船只的位置数据imoNo
是船舶标识符。以下是数据帧的示例:
下面是复制它的代码:
# intialise data of lists.
ships_data = {'imoNo':[9321483, 9321483, 9321483, 9321483, 9321483],
'Timestamp':['2020-02-22 00:00:00', '2020-02-22 00:10:00', '2020-02-22 00:20:00', '2020-02-22 00:30:00', '2020-02-22 00:40:00'],
'Position Longitude':[127.814598, 127.805634, 127.805519, 127.808548, 127.812370],
'Position Latitude':[33.800232, 33.801899, 33.798885, 33.795799, 33.792931]}
# Create DataFrame
ships_df = pd.DataFrame(ships_data)
我需要做的是在数据帧的末尾添加一列,它将标识船只航行的sea_name
。类似于下面的一个:
为了达到目的,我在this链接(IHO Sea Areas v3)上找到了一个.shp格式的数据集,如下所示:
所以,我这样做的方式是遍历ships数据集的每个(long,lat),检查其中哪个多边形是该对,最后返回匹配多边形的海的名称。这是我的代码:
### Load libraries
import numpy as np
import pandas as pd
import geopandas as gp
import shapely.speedups
from shapely.geometry import Point, Polygon
shapely.speedups.enable()
### Check and map lon lat pair with sea name
def get_seaname(long,lat):
pnt = Point(long,lat)
for i,j in enumerate(iho_df.geometry):
if pnt.within(j):
return iho_df.NAME.iloc[i]
### Apply the above function to the dataframe
ships_df['sea_name'] = ships_df.apply(lambda x: get_seaname(x['Position Longitude'], x['Position Latitude']), axis=1)
然而,这是一个非常耗时的过程。我在我的Mac电脑上测试了前1000排舰船,运行大约需要1分钟。如果它呈线性增长,那么整个数据集大约需要14天:-D
任何优化上述功能的想法都将不胜感激
谢谢大家!
最后,我有一个比最初的问题更快的问题
首先,我使用IHO海域数据集的信息创建了一个描述边界框的多边形
然后,我更改了函数,以便首先查看bbox(这比几何体快得多,因为它只是一个矩形)。当一个点落在多个长方体(用于海洋边界)内时,它会查看初始多边形,以便在匹配的长方体(而不是所有多边形)中找到正确的海洋名称
这一次大大缩短了时间。为了进一步提高性能,我使用多处理器在CPU内核之间进行并行处理。这个想法来自另一个StackOverflow帖子,我现在不记得了,但下面是代码
最后,我没有对get_seaname()使用apply函数,而是将其用于parallelize_dataframe()函数,以便在所有可用的CPU内核上运行:
我希望我的解决方案也能帮助其他人
试试这个
使用apply(无法实现更快的方法,欢迎帮助)
现在将函数矢量化,以处理点
现在,由于您的方法适用于单个点,请将点列转换为点对象的向量,并对您的方法进行向量化
相关问题 更多 >
编程相关推荐