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

如何将CSV中Matlab datenum读入Pandas为带时区感知datetime并解决兼容警告

警告产生原因
  • Pandas 2.0+版本正式将read_csv方法中的date_parser参数标记为待废弃,未来版本会完全移除该参数,触发FutureWarning的核心原因是官方不再推荐在读取CSV阶段逐行调用自定义日期解析函数:旧实现逐行执行Python函数性能极低,且无法适配Pandas内部向量化的日期类型优化逻辑,官方统一要求日期转换逻辑通过pd.to_datetime方法实现。
  • 原有代码还存在一个隐性问题:定义的col_names仅包含5个字段,但实际CSV每行有6列(第一列为Matlab datenum日期值),旧版本Pandas会隐式将第一列作为行索引解析,不会抛出列数不匹配错误,这种隐式处理很容易在版本升级后触发数据错位问题。
适配未来版本的最优实现(高性能向量化方案)

不需要逐行写转换函数,利用Matlab datenum的固定偏移规则直接做向量化转换,性能比逐行循环高10~100倍,完全符合Pandas未来版本规范:

import pandas as pd

full_fname = "some_file_with_matlab_dates.csv"
# 补全6列对应的列名,第一列为存储Matlab datenum的原始列
col_names = ("matlab_datenum", "col1", "col2", "col3", "col4", "col5")

# 第一步:读取CSV时不做任何日期解析,将所有列按原始数值类型读入
some_df = pd.read_csv(full_fname, header=None, names=col_names)

# 第二步:向量化转换日期
# 固定偏移说明:Matlab datenum以公元0年1月1日为起点,Pandas时间戳以1970年1月1日UTC为起点,两者固定相差719529天
some_df["datetime"] = (
    pd.to_datetime(some_df["matlab_datenum"] - 719529, unit="D")
    .dt.tz_localize("America/Vancouver")
)

# 如果需要和原有输出格式保持一致,将日期设为索引并删除原始datenum列
some_df = some_df.set_index("datetime").drop(columns=["matlab_datenum"])

转换结果和原有逻辑完全一致:示例值734622.540972会被正确转换为温哥华时区的2011-04-29 12:58:59.981000-07:00。

兼容自定义转换函数的写法

如果转换逻辑比较复杂,必须保留原有自定义函数,也不要在read_csv中传入date_parser参数,读完数据后通过pd.to_datetime包裹转换结果即可:

import datetime as dt
import pytz as tz
import pandas as pd

def convert_matlab_date(matlab_datenum):
    python_datetime = dt.datetime.fromordinal(int(
        matlab_datenum)) + dt.timedelta(days=matlab_datenum % 1) - dt.timedelta(days=366)
    some_tz = tz.timezone('America/Vancouver')
    new_dt = some_tz.localize(python_datetime)
    return new_dt

full_fname = "some_file_with_matlab_dates.csv"
col_names = ("matlab_datenum", "col1", "col2", "col3", "col4", "col5")
some_df = pd.read_csv(full_fname, header=None, names=col_names)
# 用pd.to_datetime包裹自定义转换结果,不会触发警告
some_df["datetime"] = pd.to_datetime(some_df["matlab_datenum"].apply(convert_matlab_date))
some_df = some_df.set_index("datetime").drop(columns=["matlab_datenum"])

注意:该写法为逐行Python循环,仅适合数据量较小的场景,大数据量下优先使用前面的向量化方案。

内容的提问来源于stack exchange,提问作者Buddy Li

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 20:36:27