Pandas DataFrame多列时间格式转换的最优实现方法问询
Pandas时间列转换:apply实现与高效方案
问题背景
我用Python的Pandas框架,需要对表格中的4列(Col1、Col2、Col3、Col4)执行三个转换操作:
- 提取Unix Timestamp
- 将Unix Timestamp转换为Datetime
- 将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报错等问题。
核心问题
- 如何用
apply方法对多列执行内联转换,复现现有代码的逻辑? - 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
相关产品推荐
相关产品推荐

