将大型位置数据帧的东距和北距快速转换为纬度和经度
Fast conversion of easting and northing to latitude and longitude for a large DataFrame of locations
我正在使用 Pandas 和 PyProj 将东距和北距转换为经度和纬度,然后像这样将拆分输出保存为 2 列....
v84 = Proj(proj="latlong",towgs84="0,0,0",ellps="WGS84")
v36 = Proj(proj="latlong", k=0.9996012717, ellps="airy",
towgs84="446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894")
vgrid = Proj(init="world:bng")
def convertLL(row):
easting = row['easting']
northing = row['northing']
vlon36, vlat36 = vgrid(easting, northing, inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
row['longitude'] = converted[0]
row['latitude'] = converted[1]
return row
values = pd.read_csv("values.csv")
values = values.apply(convertLL, axis=1)
这是可行的,但速度很慢,而且在较大的数据集上会超时。为了改进,我试图将其转换为使用 lamba 函数,希望能加快速度。到目前为止我有这个...
def convertLL(easting, northing):
vlon36, vlat36 = vgrid(easting, northing, inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
row = row['longitude'] = converted[0]
return row
values ['longitude'] = values.apply(lambda row: convertLL(row['easting'], row['northing']), axis=1)
这个转换后的版本正在运行,比我的旧版本更快,并且在更大的数据集上不会超时,但这只适用于经度,有没有办法让它也做纬度?
另外,这是向量化的吗?我可以再加快速度吗?
编辑
数据样本...
name | northing | easting | latitude | longitude
------------------------------------------------
tl1 | 378778 | 366746 | |
tl2 | 384732 | 364758 | |
因为题材问题,我想我们是只见树木不见森林。如果我们查看 the docs for transform
,您会看到:
- xx (scalar or array (numpy or python)) – Input x coordinate(s).
- yy (scalar or array (numpy or python)) – Input y coordinate(s).
太棒了; numpy 数组正是我们所需要的。 A pd.DataFrame
可以被认为是数组的字典,所以我们只需要隔离那些列并将它们传递给函数。有一个小问题 - DataFrame
的列将是 Series
,transform
将拒绝,所以我们只需要使用 values
属性。这个迷你示例直接等同于您的初始方法:
def vectorized_convert(df):
vlon36, vlat36 = vgrid(df['easting'].values,
df['northing'].values,
inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
df['longitude'] = converted[0]
df['latitude'] = converted[1]
return df
df = pd.DataFrame({'northing': [378778, 384732],
'easting': [366746, 364758]})
print(vectorized_convert(df))
我们完成了。除此之外,我们可以查看 100 行的时间(当前方法对于我通常的 100,000 行的时间示例来说是爆炸性的):
def current_way(df):
df = df.apply(convertLL, axis=1)
return df
def vectorized_convert(df):
vlon36, vlat36 = vgrid(df['easting'].values,
df['northing'].values,
inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
df['longitude'] = converted[0]
df['latitude'] = converted[1]
return df
df = pd.DataFrame({'northing': [378778, 384732] * 50,
'easting': [366746, 364758] * 50})
给出:
%timeit current_way(df)
289 ms ± 15.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vectorized_convert(df)
2.95 ms ± 59.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我正在使用 Pandas 和 PyProj 将东距和北距转换为经度和纬度,然后像这样将拆分输出保存为 2 列....
v84 = Proj(proj="latlong",towgs84="0,0,0",ellps="WGS84")
v36 = Proj(proj="latlong", k=0.9996012717, ellps="airy",
towgs84="446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894")
vgrid = Proj(init="world:bng")
def convertLL(row):
easting = row['easting']
northing = row['northing']
vlon36, vlat36 = vgrid(easting, northing, inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
row['longitude'] = converted[0]
row['latitude'] = converted[1]
return row
values = pd.read_csv("values.csv")
values = values.apply(convertLL, axis=1)
这是可行的,但速度很慢,而且在较大的数据集上会超时。为了改进,我试图将其转换为使用 lamba 函数,希望能加快速度。到目前为止我有这个...
def convertLL(easting, northing):
vlon36, vlat36 = vgrid(easting, northing, inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
row = row['longitude'] = converted[0]
return row
values ['longitude'] = values.apply(lambda row: convertLL(row['easting'], row['northing']), axis=1)
这个转换后的版本正在运行,比我的旧版本更快,并且在更大的数据集上不会超时,但这只适用于经度,有没有办法让它也做纬度?
另外,这是向量化的吗?我可以再加快速度吗?
编辑
数据样本...
name | northing | easting | latitude | longitude
------------------------------------------------
tl1 | 378778 | 366746 | |
tl2 | 384732 | 364758 | |
因为题材问题,我想我们是只见树木不见森林。如果我们查看 the docs for transform
,您会看到:
- xx (scalar or array (numpy or python)) – Input x coordinate(s).
- yy (scalar or array (numpy or python)) – Input y coordinate(s).
太棒了; numpy 数组正是我们所需要的。 A pd.DataFrame
可以被认为是数组的字典,所以我们只需要隔离那些列并将它们传递给函数。有一个小问题 - DataFrame
的列将是 Series
,transform
将拒绝,所以我们只需要使用 values
属性。这个迷你示例直接等同于您的初始方法:
def vectorized_convert(df):
vlon36, vlat36 = vgrid(df['easting'].values,
df['northing'].values,
inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
df['longitude'] = converted[0]
df['latitude'] = converted[1]
return df
df = pd.DataFrame({'northing': [378778, 384732],
'easting': [366746, 364758]})
print(vectorized_convert(df))
我们完成了。除此之外,我们可以查看 100 行的时间(当前方法对于我通常的 100,000 行的时间示例来说是爆炸性的):
def current_way(df):
df = df.apply(convertLL, axis=1)
return df
def vectorized_convert(df):
vlon36, vlat36 = vgrid(df['easting'].values,
df['northing'].values,
inverse=True)
converted = transform(v36, v84, vlon36, vlat36)
df['longitude'] = converted[0]
df['latitude'] = converted[1]
return df
df = pd.DataFrame({'northing': [378778, 384732] * 50,
'easting': [366746, 364758] * 50})
给出:
%timeit current_way(df)
289 ms ± 15.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit vectorized_convert(df)
2.95 ms ± 59.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)