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

时间:2016-04-25 21:58:27

标签: python pandas geocoding

我希望将一系列坐标存储在pandas数据框中并定义一个函数,该函数将遍历每个条目,将其转换(BNG Easting Northing to 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

3 个答案:

答案 0 :(得分:1)

假设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)) 

答案 1 :(得分:1)

我认为该功能正常,但输入的格式是罪魁祸首。在样本数据的第五行中,SHLAA和日期之间没有空格 - 它们作为一个表达式进入LA Ref列,而北向列得到NaN。此NaN值会在函数RuntimeError: b'non-convergent inverse meridional dist'中生成pyproj.transform

在那里添加一个空格,再加上一些需要重新格式化的列名称,它工作正常(或者至少看起来如此)。

我的代码:

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

答案 2 :(得分:0)

正如@ptrj所说;

RuntimeError: non-convergent inverse meridional dist

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