Javier
Javier

Reputation: 513

How to convert lat/lon values to decimal in python?

I have Latitude and Longitude Columns in a dataframe like this:

   Station      Latitude     Longitude
0        1  18° 23' 20.9  72° 23' 25.9
1        2  17° 22' 20.5  73° 22' 21.5
       etc           etc           etc

With a space between the values. I want to convert the lat lon values to decimal (float)

I tried this code:

def dms2dd(s):   
    degrees, minutes, seconds = re.split('[°\'\ ]+', s)
    dd = -1*float(degrees) -1*float(minutes)/60 -1*float(seconds)/(60*60);
    return dd

df['LATITUDE'] = df['LATITUDE'].apply(dms2dd)
df['LONGITUDE'] = df['LONGITUDE'].apply(dms2dd)

But gets me an error:

ValueError: too many values to unpack (expected 3).

The Stations are in the south hemisphere (thats why i use (-) in the function).

Can you help me please?

Upvotes: 2

Views: 1540

Answers (2)

Elliott Collins
Elliott Collins

Reputation: 770

That code works for the four values in your example

That error indicates that some value in your data has an extra delimiting character so that the regex split is sending back more than three values (e.g. a trailing space).

You might get away with just passing df['LATITUDE'].str.strip().apply(dms2dd) if that's the only problem, but you should probably either set a more robust regex pattern that allows for spaces or clean up the formatting before sending to dms2dd.

Upvotes: 1

Shubham Sharma
Shubham Sharma

Reputation: 71689

Use Series.str.extract along with the given regex pattern to extract the degree, minutes and seconds components from the given geographical coordinates, then the DMS value is converted to decimal degrees using the formula (Note: if the coordinates are from southern or western hemisphere you can adjust the formula accordingly):

pattern = r'(?P<d>[\d\.]+).*?(?P<m>[\d\.]+).*?(?P<s>[\d\.]+)'

dms = df['Latitude'].str.extract(pattern).astype(float)
df['LATITUDE'] = dms['d'] + dms['m'].div(60) + dms['s'].div(3600)

# Similarly we do for the longitude    
dms = df['Longitude'].str.extract(pattern).astype(float)
df['LONGITUDE'] = dms['d'] + dms['m'].div(60) + dms['s'].div(3600)

Result:

# print(df)

   Station      Latitude     Longitude   LATITUDE  LONGITUDE
0        1  18° 23' 20.9  72° 23' 25.9  18.389139  72.390528
1        2  17° 22' 20.5  73° 22' 21.5  17.372361  73.372639

Upvotes: 3

Related Questions