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

Pandas DataFrame多列时间格式转换的最优实现方法问询

Pandas时间列转换:apply实现与高效方案

问题背景

我用Python的Pandas框架,需要对表格中的4列(Col1、Col2、Col3、Col4)执行三个转换操作:

  1. 提取Unix Timestamp
  2. 将Unix Timestamp转换为Datetime
  3. 将Datetime转换为本地时区(澳大利亚悉尼)

现有代码如下:

import pandas as pd

data = [
    {"Col1": "/Date(1591020000000)/", "Col2": "/Date(1591020000000)/", "Col3": "/Date(1591020000000)/", "Col4": "/Date(1591020000000)/", "Col5": 1},
    {"Col1": "/Date(1591020000000)/", "Col2": "/Date(1591020000000)/", "Col3": "/Date(1591020000000)/", "Col4": "/Date(1591020000000)/", "Col5": 2},
    {"Col1": "/Date(1591020000000)/", "Col2": "/Date(1591020000000)/", "Col3": "/Date(1591020000000)/", "Col4": "/Date(1591020000000)/", "Col5": 3},
    {"Col1": "/Date(1591020000000)/", "Col2": "/Date(1591020000000)/", "Col3": "/Date(1591020000000)/", "Col4": "/Date(1591020000000)/", "Col5": 4}
]
df = pd.json_normalize(data)

for col in ['Col1', 'Col2', 'Col3', 'Col4']:
    df[col] = df[col].str.extract(r'\(([^\)]+)\)', expand=False)
    df[col] = pd.to_datetime(df[col], unit='ms').dt.tz_localize('UTC').dt.tz_convert('Australia/Sydney').dt.strftime('%d/%m/%Y')

作为Pandas新手,我觉得当前循环处理的方式不够优化,尝试过用apply方法(自定义函数或lambda)处理,但遇到结果异常、NaN报错等问题。

核心问题

  1. 如何用apply方法对多列执行内联转换,复现现有代码的逻辑?
  2. Pandas中执行这类数据转换的最优高效方法是什么?

解答

1. 用apply实现转换逻辑

你可以定义一个完整的转换函数,批量应用到目标列,同时处理NaN避免报错:

import pandas as pd

def convert_date_col(series):
    # 提取时间戳,空值自动转为NaN
    ts_series = series.str.extract(r'\(([^\)]+)\)', expand=False)
    # 转换为时间类型,无效值转为NaT(时间类型的空值)
    dt_series = pd.to_datetime(ts_series, unit='ms', errors='coerce')
    # 时区转换并格式化,NaT会保留为NaN
    return dt_series.dt.tz_localize('UTC').dt.tz_convert('Australia/Sydney').dt.strftime('%d/%m/%Y')

# 对目标列批量应用函数
df[['Col1', 'Col2', 'Col3', 'Col4']] = df[['Col1', 'Col2', 'Col3', 'Col4']].apply(convert_date_col)

如果想用lambda内联实现(适合简单逻辑,可读性稍弱):

df[['Col1', 'Col2', 'Col3', 'Col4']] = df[['Col1', 'Col2', 'Col3', 'Col4']].apply(
    lambda s: pd.to_datetime(s.str.extract(r'\(([^\)]+)\)', expand=False), unit='ms', errors='coerce')
               .dt.tz_localize('UTC').dt.tz_convert('Australia/Sydney').dt.strftime('%d/%m/%Y')
)

关键注意点:

  • 使用errors='coerce'让无效值转为NaT,避免因空值或非法格式报错
  • apply默认按列操作(axis=0),直接传入多列即可批量处理

2. Pandas中最优高效的转换方法

Pandas的向量化操作是最高效的方案——你的原始循环其实已经用到了向量化API,但可以优化为更简洁的批量处理:

优化方案:批量提取+批量转换

# 批量提取所有目标列的时间戳(用正则替换直接提取数字)
ts_df = df[['Col1', 'Col2', 'Col3', 'Col4']].replace(r'/Date\((\d+)\)/', r'\1', regex=True).astype(float)

# 一次性完成时间转换、时区调整和格式化
df[['Col1', 'Col2', 'Col3', 'Col4']] = pd.to_datetime(ts_df, unit='ms')\
    .dt.tz_localize('UTC')\
    .dt.tz_convert('Australia/Sydney')\
    .dt.strftime('%d/%m/%Y')

为什么这个更高效?

  • replace+astype比str.extract在批量处理时性能更优(数据量大时差异明显)
  • 全程对整个DataFrame执行向量化操作,避免了循环或apply的Python级别的遍历开销
  • Pandas的向量化API基于C实现,速度远快于Python循环

性能对比结论:

  • 数据量小时,apply和向量化操作差异不大
  • 数据量较大时,批量向量化操作的速度是循环或apply的数倍甚至数十倍

内容的提问来源于stack exchange,提问作者Wesley Jeftha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:22:15