Reputation: 513
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
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
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