Search code examples
pythonpandasdataframegeopandasgeography

How to convert coordinates for use in GeoPandas? (e.g., 37_N)


I have the following dataframe:

import pandas as pd
df_coords = pd.DataFrame({'lat': {'1010': '37_N',
  '1050': '32_N',
  '1059': '19_N',
  '1587': '6_S',
  '3367': '44_N'},
 'lon': {'1010': '65_W',
  '1050': '117_W',
  '1059': '156_W',
  '1587': '106_E',
  '3367': '12_E'}})

and I'm trying to convert these coordinates so I can build a GeoPandas dataframe object but I can't seem to figure out how to convert the strings.

import geopandas as gpd
gpd.points_from_xy(x=["37_N"], y=["65_W"])
# ---------------------------------------------------------------------------
# ValueError                                Traceback (most recent call last)
# <ipython-input-36-a02c9f8a011d> in <module>
# ----> 1 gpd.points_from_xy(x=["37_N"], y=["65_W"])

# ~/anaconda3/envs/soothsayer_py3.8_env/lib/python3.8/site-packages/geopandas/array.py in points_from_xy(x, y, z, crs)
#     256     output : GeometryArray
#     257     """
# --> 258     return GeometryArray(vectorized.points_from_xy(x, y, z), crs=crs)
#     259 
#     260 

# ~/anaconda3/envs/soothsayer_py3.8_env/lib/python3.8/site-packages/geopandas/_vectorized.py in points_from_xy(x, y, z)
#     241 def points_from_xy(x, y, z=None):
#     242 
# --> 243     x = np.asarray(x, dtype="float64")
#     244     y = np.asarray(y, dtype="float64")
#     245     if z is not None:

# ~/anaconda3/envs/soothsayer_py3.8_env/lib/python3.8/site-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
#      83 
#      84     """
# ---> 85     return array(a, dtype, copy=False, order=order)
#      86 
#      87 

# ValueError: could not convert string to float: '37_N'

Can anyone describe how to convert the N,S,W,E info in relation to the actual coordinates for GeoPandas?


Solution

  • You would need to map your values into a range between -180 and 180 both for longitude and latitude. Here the geopandas documentation

    Here is a function that does that.

    def convert_value(value):
    
        if value.endswith('_N') or value.endswith('_E'):
    
            return int(value[:-2])
    
        if value.endswith('_S') or value.endswith('_W'):
    
            return -int(value[:-2])
    

    The input the value you want to convert for example "12_W". The function will return "-12". No guarantee of what value should be negative and what should be positive. I just set the minus at the place it made the most sense.

    geopandas.points_from_xy(value_longitude, value_latitude, crs="EPSG:4326")