在 pandas 系列中转换坐标并附加为附加系列的函数

Function to convert coordinates in pandas series and append as additional series

我正在寻找存储在 pandas 数据框中的一系列坐标,并定义一个函数来遍历每个条目,将其转换(BNG Easting Northing 到 Lat 和 Long)并保存它到同一行中的新列。 Elise Huard 的 function 看起来应该做到这一点

def proj_transform(df):
    #bng = pyproj.Proj(init='epsg:27700')
    bng = pyproj.Proj("+init=EPSG:27700")
    #wgs84 = pyproj.Proj(init='epsg:4326')
    wgs84 = pyproj.Proj("+init=EPSG:4326")
    lats = pd.Series()
    lons = pd.Series()
    for idx, val in enumerate(df['Easting']):
        lon, lat = pyproj.transform(bng,wgs84,df['Easting'][idx], df['Northing'][idx])
        lats.set_value(idx, lat)
        lons.set_value(idx, lon)
    df['lat'] = lats
    df['lon'] = lons
    return df

但是我在尝试 运行 函数后收到以下错误。关于可能导致它的原因的任何建议或作为工作回合的替代方法。

RuntimeError: non-convergent inverse meridional dist

使用的数据样本;

Site Reference  LA Reference    Start Date  Easting Northing
0   380500145   NaN 20130101    105175.0    105175.0
1   380500128   NaN 20060331    104000.0    104000.0
2   380500085   NaN 20030401    105055.0    105055.0
3   380500008   NaN 19980930    108480.0    108480.0
4   380500009   NaN 19980930    105415.0    105415.0
5   380500136   SHLAA20100101   105081.0    105081.0
6   380500038   NaN 19980930    105818.0    105818.0

假设 pyproj.transform 在单个(东、北)坐标对上正确工作,那么代替:

for idx, val in enumerate(df['Easting']):
    lon, lat = pyproj.transform(bng,wgs84,df['Easting'][idx], df['Northing'][idx])
    lats.set_value(idx, lat)
    lons.set_value(idx, lon)

尝试:

lons, lats = map(lambda x: pyproj.transform(bng, wgs84, x[0], x[1]),
                 zip(df['Easting'], df['Northing']))

其他不变。

编辑

这个有效:

arr = map(lambda x: pyproj.transform(bng, wgs84, x[0], x[1]),
          zip(df['eastings'], df['northings']))
lons, lats = map(array, zip(*arr)) 

我认为该功能运行良好,但您输入的格式是罪魁祸首。在示例数据的第五行中,SHLAA 和日期之间没有 space - 它们作为一个表达式进入 LA Ref 列,而 northings 列得到 NaN。此 NaN 值在函数 pyproj.transform.

中产生 RuntimeError: b'non-convergent inverse meridional dist'

在那里添加 space 后,加上一些需要的列名重新格式化,它工作正常(或者至少看起来是这样)。

我的代码:

import pandas as pd
import pyproj
from inspect import cleandoc
from io import StringIO

s = '''
    Site_Reference  LA_Reference    Start_Date  eastings northings
    0   380500145   NaN 20130101    105175.0    105175.0
    1   380500128   NaN 20060331    104000.0    104000.0
    2   380500085   NaN 20030401    105055.0    105055.0
    3   380500008   NaN 19980930    108480.0    108480.0
    4   380500009   NaN 19980930    105415.0    105415.0
    5   380500136   SHLAA 20100101   105081.0    105081.0
    6   380500038   NaN 19980930    105818.0    105818.0
    '''
s = cleandoc(s)
df = pd.read_csv(StringIO(s), sep = '\s+')
print(df)
   Site_Reference LA_Reference  Start_Date  eastings  northings
0       380500145          NaN    20130101    105175     105175
1       380500128          NaN    20060331    104000     104000
2       380500085          NaN    20030401    105055     105055
3       380500008          NaN    19980930    108480     108480
4       380500009          NaN    19980930    105415     105415
5       380500136        SHLAA    20100101    105081     105081
6       380500038          NaN    19980930    105818     105818

def proj_transform(df):
    bng = pyproj.Proj("+init=EPSG:27700")
    wgs84 = pyproj.Proj("+init=EPSG:4326")
    lats = pd.Series()
    lons = pd.Series()
    for idx, val in enumerate(df['eastings']):
        lon, lat = pyproj.transform(bng,wgs84,df['eastings'][idx], df['northings'][idx])
        lats.set_value(idx, lat)
        lons.set_value(idx, lon)
    df['lat'] = lats
    df['lon'] = lons
    return df

df_transformed = proj_transform(df)

print(df_transformed)
   Site_Reference LA_Reference  Start_Date  eastings  northings        lat       lon
0       380500145          NaN    20130101    105175     105175  50.771035 -6.183048
1       380500128          NaN    20060331    104000     104000  50.759899 -6.198721
2       380500085          NaN    20030401    105055     105055  50.769898 -6.184649
3       380500008          NaN    19980930    108480     108480  50.802348 -6.138924
4       380500009          NaN    19980930    105415     105415  50.773309 -6.179846
5       380500136        SHLAA    20100101    105081     105081  50.770144 -6.184302
6       380500038          NaN    19980930    105818     105818  50.777128 -6.174468

如@ptrj 所述;

RuntimeError: non-convergent inverse meridional dist

在这种情况下,是由数据中的 NaN 值引起的。