如何快速为2000行DataFrame的经纬度计算时区小时
问题描述
我有一个包含2000行的DataFrame,包含latitude(纬度)和longitude(经度)列,想要新增timezone_hours列存储每行经纬度对应的时区小时数。尝试过多种方法都没达到预期效果,用TimezoneFinder处理2000行耗时长达10分钟,不符合要求,寻求能在2分钟内完成计算的高效实现方案或代码。
示例数据
输入DataFrame:
data = [['23', 35.5, 30.6], ['12', 30.6, 31.3444], ['15', 35.9, 24.5], ['14', 40.5, 38.6]] columns = ['key', 'latitude', 'longitude'] df = pd.DataFrame(data, columns=columns)
期望输出DataFrame:
data = [['23', 35.5, 30.6, +3], ['12', 30.6, 31.3444, -6], ['15', 35.9, 24.5, +7], ['14', 40.5, 38.6, +5]] columns = ['key', 'latitude', 'longitude', 'timezone_hours']
高效解决方案
方案1:FastTimezoneFinder + 重复坐标缓存
TimezoneFinder默认实现性能有限,换成FastTimezoneFinder可大幅提速;同时先对重复经纬度去重计算,避免冗余操作,这对2000行数据的优化效果非常明显。
import pandas as pd from timezonefinder import FastTimezoneFinder import pytz # 初始化快速时区查找器 tf = FastTimezoneFinder() def get_timezone_offset(lat, lon): # 获取时区名称 tz_name = tf.timezone_at(lng=lon, lat=lat) if not tz_name: # 无法识别时返回None,可根据需求替换为默认值 return None # 计算当前UTC偏移小时数(含夏令时) tz = pytz.timezone(tz_name) current_offset = tz.utcoffset(pd.Timestamp.now()).total_seconds() / 3600 return current_offset # 步骤1:提取唯一经纬度对,减少重复计算 unique_coords = df[['latitude', 'longitude']].drop_duplicates().reset_index(drop=True) # 步骤2:批量计算唯一坐标的时区偏移 unique_coords['timezone_hours'] = unique_coords.apply( lambda row: get_timezone_offset(row['latitude'], row['longitude']), axis=1 ) # 步骤3:合并回原DataFrame df = df.merge(unique_coords, on=['latitude', 'longitude'], how='left')
方案2:矢量化/并行计算(无重复坐标场景)
如果你的经纬度几乎没有重复,可使用swifter库自动选择最优处理方式(矢量化或并行运算),进一步压缩耗时:
import pandas as pd from timezonefinder import FastTimezoneFinder import pytz import swifter tf = FastTimezoneFinder() def get_timezone_offset(lat, lon): tz_name = tf.timezone_at(lng=lon, lat=lat) if not tz_name: return None tz = pytz.timezone(tz_name) current_offset = tz.utcoffset(pd.Timestamp.now()).total_seconds() / 3600 return current_offset # swifter自动优化处理逻辑,无需手动判断 df['timezone_hours'] = df.swifter.apply( lambda row: get_timezone_offset(row['latitude'], row['longitude']), axis=1 )
核心优化说明
- 替换查找器:
FastTimezoneFinder比默认实现快3-5倍,底层采用更高效的空间索引算法 - 缓存重复值:2000行数据若存在重复坐标,去重后计算量可直接减半甚至更多
- 避免逐行循环:用
apply批量处理或swifter自动矢量化,比原生for loop效率高一个数量级 - 夏令时适配:如果需要固定时区偏移(忽略夏令时),可将
tz.utcoffset(now)替换为tz._utcoffset
内容的提问来源于stack exchange,提问作者ninja_minida
相关产品推荐
相关产品推荐

