如何为整个DataFrame将经纬度转换为十进制度数?
解决DataFrame中经纬度转换为十进制度数的报错问题
问题背景
转换单个经纬度字符串为十进制度数的代码可以正常运行,但处理DataFrame中的经纬度列时,出现AttributeError: 'Series' object has no attribute 'split'错误,遍历DataFrame时也会出现类似的'DataFrame' object has no attribute 'split'错误。
用户提供的代码示例:
# 单个坐标转换(正常运行) latitude = "20-18-6.65N" N = 'N' in latitude d, m, s = map(float, latitude[:-1].split('-')) latitude = (d + m / 60. + s / 3600.) * (1 if N else -1) longitude = "40-17-12.13W" W = 'W' in longitude d, m, s = map(float, longitude[:-1].split('-')) longitude = (d + m / 60. + s / 3600.) * (-1 if W else 1) print(latitude) print(longitude) latitude = ("20-18-6.65N") longitude = ("40-17-12.13W") latitude = sum(float(x) / 60 ** n for n, x in enumerate(latitude[:-1].split('-'))) * (1 if 'N' in latitude[-1] else -1) longitude = sum(float(x) / 60 ** n for n, x in enumerate(longitude[:-1].split('-'))) * (1 if 'E' in longitude[-1] else -1) print(latitude, longitude) # 处理DataFrame时报错 latlong = df.iloc[:, 0:3] # Subset for columns needed. latlong_df = pd.DataFrame(data = latlong) # transform into pandas df. lats_df = latlong_df.iloc[:, 1] # subset for latitude column. longs_df = latlong_df.iloc[:, 2] # subset for longitude column. for i in latlong_df: lats_df = sum(float(x) / 60 ** n for n, x in enumerate(lats_df[:-1].split('-'))) * (1 if 'N' in lats_df[-1] else -1) longs_df = sum(float(x) / 60 ** n for n, x in enumerate(longs_df[:-1].split('-'))) * (1 if 'E' in longs_df[-1] else -1) print(lats_df, longs_df)
错误原因
split()是Python字符串对象的方法,而lats_df、longs_df是Pandas的Series对象(代表DataFrame的一列),直接对Series调用split()会触发属性错误。遍历DataFrame时,循环变量是列名,也无法直接调用split()。
解决方案
方法1:使用Pandas字符串方法(str.split)批量处理
利用Pandas的str属性,对Series中的每个字符串元素批量应用字符串操作:
import pandas as pd # 假设你的DataFrame为df,纬度列索引为1,经度列索引为2 latlong_df = df.iloc[:, 0:3] # 处理纬度列 # 提取方向字符(N/S) lat_direction = latlong_df.iloc[:,1].str[-1] # 拆分度分秒并转为数值 lat_parts = latlong_df.iloc[:,1].str[:-1].str.split('-', expand=True).astype(float) # 计算十进制度纬度 latlong_df['decimal_lat'] = (lat_parts[0] + lat_parts[1]/60 + lat_parts[2]/3600) * lat_direction.map({'N':1, 'S':-1}) # 处理经度列 lon_direction = latlong_df.iloc[:,2].str[-1] lon_parts = latlong_df.iloc[:,2].str[:-1].str.split('-', expand=True).astype(float) latlong_df['decimal_lon'] = (lon_parts[0] + lon_parts[1]/60 + lon_parts[2]/3600) * lon_direction.map({'E':1, 'W':-1}) print(latlong_df[['decimal_lat', 'decimal_lon']])
方法2:编写转换函数,用apply逐元素处理
先定义一个通用的经纬度转换函数,再对Series的每个元素应用该函数:
import pandas as pd def coord_to_decimal(coord_str): # 提取方向 direction = coord_str[-1] # 拆分度、分、秒 d, m, s = map(float, coord_str[:-1].split('-')) # 计算十进制值 decimal_val = d + m/60 + s/3600 # 根据方向调整正负 if direction in ['S', 'W']: decimal_val *= -1 return decimal_val latlong_df = df.iloc[:, 0:3] # 对纬度列应用函数 latlong_df['decimal_lat'] = latlong_df.iloc[:,1].apply(coord_to_decimal) # 对经度列应用函数 latlong_df['decimal_lon'] = latlong_df.iloc[:,2].apply(coord_to_decimal) print(latlong_df[['decimal_lat', 'decimal_lon']])
这两种方法都能避免直接对Series/DataFrame调用split()的错误,高效完成批量转换。
内容的提问来源于stack exchange,提问作者Sawyer H
相关产品推荐
相关产品推荐

