You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何快速为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:25:35