拯救pandas计划(11)——转换DataFrame内的字符串型日期为日期类型

本文介绍了如何使用pandas的to_datetime方法将字符串类型的日期数据转换为日期类型,包括错误处理、格式设定、时间单位转换和效率提升等关键点,帮助数据工作者更高效地处理日期数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拯救pandas计划(11)——转换DataFrame内的字符串型日期为日期类型

最近发现周围的很多小伙伴们都不太乐意使用pandas,转而投向其他的数据操作库,身为一个数据工作者,基本上是张口pandas,闭口pandas了,故而写下此系列以让更多的小伙伴们爱上pandas。

系列文章说明:

系列名(系列文章序号)——此次系列文章具体解决的需求

平台:

  • windows 10
  • python 3.8
  • pandas >=1.2.4

/ 数据需求

目前有这么一列日期数据,不过是以字符串类型显示的,需要转换成日期类型。

date
02021-11-27 00:00:00
12021-12-17 00:00:00
22021-12-17 00:00:00
32021-12-16 12:00:00
42021-12-17 00:00:00
52021-12-17 00:00:00
62021-12-02 00:00:00
72021-11-13 00:00:00
82021-12-17 00:00:00
92021-11-18 12:00:00
102021-12-16 12:00:00

/ 需求拆解

在python中就有很多关于日期处理的库,数最常见常用的就是datetime库了,在pandas里也有处理日期的方法pandas.to_datetime,粗略的看了下该方法的解释文档,基于datetime库做了更多扩展,在pandas里使用to_datetime方法更轻便的转换日期类型数据。

/ 需求处理

在这一例中,可以简单使用pd.to_datetime(data['date'])即可,不用指定转换的类型,它会自动寻找到符合的日期类型进行转换。

>>> import pandas as pd
>>> df = ...

>>> df['date'].values
array([['2021-11-27 00:00:00'],
       ['2021-12-17 00:00:00'],
       ['2021-12-17 00:00:00'],
       ['2021-12-16 12:00:00'],
       ['2021-12-17 00:00:00'],
       ['2021-12-17 00:00:00'],
       ['2021-12-02 00:00:00'],
       ['2021-11-13 00:00:00'],
       ['2021-12-17 00:00:00'],
       ['2021-11-18 12:00:00'],
       ['2021-12-16 12:00:00'],
       ['2021-12-14 12:00:00'],
       ['2021-12-17 00:00:00']], dtype=object)

>>> pd.to_datetime(df['date'])

本例的需求非常容易解决,再稍微探索下它更多的用法。

pd.to_datetime(
    arg: Union[~DatetimeScalar, List, Tuple, ~ArrayLike, ForwardRef('Series')],
    errors: str = 'raise',                # 产生错误的处理方式
    dayfirst: bool = False,               # 日在首位
    yearfirst: bool = False,              # 年份在首位
    utc: Union[bool, NoneType] = None,    # 是否返回时区
    format: Union[str, NoneType] = None,  # 格式
    exact: bool = True,                   # 是否精确地按格式匹配
    unit: Union[str, NoneType] = None,    # 时间单位,默认ns
    infer_datetime_format: bool = False,  # 根据判断第一个日期作为基准,较少后续的日期推断
    origin='unix',                        # 参考日历
    cache: bool = True,
)

它的参数都是很有作用的,但也是有常用与不常用的区分,如需了解所有参数的含义,可以参考官方文档及python的内置模块datetime。下面分享几个我常用的。

  • errors,转换过程中发生错误处理

有三个选项,分别为:raise,coerce,ignore,设定后效果分别为:立即返回报错,中断代码运行;将不能转换的值用pd.NaT代替返回;忽略报错,使用原值返回,这里有个误区,只要有错误发生,它不会单独跳过这一不能转换的值,而是不会转换所有的数据以原数据类型返回。

  • format,输入的日期格式

当输入的日期不能让pd.to_datetime很好的识别转换时,就轮到它上场了。更多格式用法转:[datetime]https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior

样例:

pd.to_datetime(['03Apr2022', 
                '04-Apr-2022', 
                '2022-01-01', 
                '20220101', 
                '2022/01/01', 
                'Oct 10 2021', 
                '010122', # 日月年
                '020122', # 月日年
                '220101'], # 年月日
               unit='ns')

可以看到几个对应颜色的再转换过程出了点意外,在未设置format参数时,都可以很好的转换,在需要转换的日期列中,只要格式不是特别特殊的情况下完全不用设置format参数。

因为后面三个日期数据的年份是用两个字符组成的,且位置漂浮不定,这时设置format,设置之后也只能特定日期做转换,用法看参照datetime.datetime.strptime

# 不接收单独字符串传入,可以使用列表,元组等其他容器类型将日期字符串放进去
# 转换'010122' 日月年
>>> pd.to_datetime(['010122'], format='%d%m%y')
DatetimeIndex(['2022-01-01'], dtype='datetime64[ns]', freq=None)

# 转换'020122' 月日年
>>> pd.to_datetime(['020122'], format='%m%d%y')
DatetimeIndex(['2022-02-01'], dtype='datetime64[ns]', freq=None)

# 转换'220301' 年月日
>>> pd.to_datetime(['220301'], format='%y%m%d')
DatetimeIndex(['2022-03-01'], dtype='datetime64[ns]', freq=None)

其他格式类似。

  • infer_datetime_format,将后续的日期格式用第一个转换的日期格式匹配,默认False。

这个参数在提高转换效率上有很大的帮助,在没有设定format的情况下,将这个参数设定为True(infer_datetime_format=True),需要转换的日期类型格式高度一致时,可以极大地减少转换时间,官方称能提高5至10倍的效率。也就是说它会蒙第一个需要转换的日期格式,蒙对后,后续的日期转换都按这个来,不用再去蒙格式了。

  • unit,时间单位,默认ns

上面的例子中的都是对字符串转换,也有提到过几乎不用设置日期格式就能转换日期,还有一种在日期操作中经常会遇见的格式,就是时间戳类型的数据,这个转换为日期当然也不在话下,同样可以与上述日期转换混合在一起使用,而又注意到,转换后的时间单位都是ns,所以在未设置unit参数为其他单位时,需要传入ns为单位的时间戳数据。

可以针对时间戳数据设置不同的unit参数来转换,当然同次转换的列中单位理应一致。

# ms
>>> pd.to_datetime([1648195805123], unit='ms')
DatetimeIndex(['2022-03-25 08:10:05.123000'], dtype='datetime64[ns]', freq=None)

# s
>>> pd.to_datetime([1648195805], unit='s')
DatetimeIndex(['2022-03-25 08:10:05'], dtype='datetime64[ns]', freq=None)

# D
>>> pd.to_datetime([19076], unit='D')
DatetimeIndex(['2022-03-25'], dtype='datetime64[ns]', freq=None)
  • origin,其实日期设置

可能会好奇这些数怎么会能够跳跃到当前日期。在这里都是因为origin参数的设定,默认是unix,即起始时间为时区为0时区的1970-01-01,所以为什么在使用pd.to_datetime的时候,特别在用时间戳转换时间中有时会不对,则是此中的道理,固然可以设置origin参数,使时间戳在这个基准上进行相加,直至转换完成。

>>> pd.to_datetime([1, 2, 3], unit='D', origin=pd.Timestamp('1960-01-01'))
DatetimeIndex(['1960-01-02', '1960-01-03', '1960-01-04']

/ 总结

相信都已经了解了pd.to_datetime的相关用法,在pandas日期数据转换中不妨试试pd.to_datetime方法,结合了datetime库中datetime.strptime函数,减少其中部分参数的使用,在项目使用过程中也可以较少在意当日期格式发生变化时需要去调整日期格式,减少错误的发生,pandas中也沿用了许多datetime库中的函数,更多格式类型可参考datetime的使用文档。

这本该是青葱杨柳的天气,还是牡丹海棠的时节?


于二零二二年四月十二日作

<think>好的,用户的问题是关于如何在Pandas DataFrame中将日期时间格式的字符串转换日期时间对象。我需要仔细分析这个问题,并确保回答准确、步骤清晰。 首先,我得回想一下Pandas中处理日期时间转换的相关函数。记得pandas有一个to_datetime函数,应该就是用来做这种转换的。用户提到的引用[3]里也提到了这个函数的基本语法,所以可以引用这一点来支持回答。 接下来,我需要明确用户的使用场景。他们可能有一个包含日期字符串的DataFrame列,需要将其转换为datetime类型,以便进行时间序列分析、重采样或者时间差计算等操作。比如,用户的数据可能来自CSV文件或者数据库,读取时日期列被识别为字符串,需要转换后才能利用时间相关的功能。 然后,我应该分步骤说明如何进行操作。首先,如何创建包含日期字符串的DataFrame,这可以引用引用[2]中的创建DataFrame的方法。然后,使用pd.to_datetime函数进行转换,这里需要给出具体的代码示例,并解释参数的作用,如format参数的使用场景,以及如何处理错误(errors参数)。可能还需要提到转换后的datetime对象可以进行的操作,比如提取年份、月份等属性,或者进行时间偏移,这部分可以结合引用[4]中的时间频率模块来说明。 另外,用户可能遇到的情况包括不同的日期格式,比如日在前还是月在前,或者包含时间信息。需要给出不同格式的例子,并说明如何正确指定format参数。同时,如果原始数据中存在无法转换的字符串,如何处理错误,比如强制转换为NaT或者忽略错误,这也是需要注意的地方。 可能还需要提到在读取数据时直接进行转换的方法,比如在read_csv中使用parse_dates参数,这样可以一步到位,避免后续再转换。这也是一个实用的技巧,用户可能不知道,所以值得指出。 最后,需要确保回答中所有的代码示例都符合Pandas的语法,并且正确使用LaTeX格式。比如,函数名和参数使用$符号包裹,如pd.to_datetime(),确保格式正确。同时,按照用户的要求,生成相关的问题,比如如何处理不同格式的日期转换后的常见操作等,这些问题需要与主题紧密相关,帮助用户进一步学习。 总结一下,回答的结构应该是:介绍pd.to_datetime函数,分步骤示例,处理不同格式和错误的情况,读取时直接转换的方法,转换后的操作示例,以及相关引用。同时,生成的问题要覆盖用户可能感兴趣的扩展内容。</think>在PythonPandas中,将日期时间格式的字符串转换日期时间对象主要通过`pd.to_datetime()`函数实现。以下是具体步骤和示例: ### 步骤说明 1. **基础转换** 直接应用`pd.to_datetime()`函数将字符串列转换为datetime对象: ```python import pandas as pd # 创建包含日期字符串的DataFrame[^2] df = pd.DataFrame({'date_str': ['2023-01-15', '2023-02-20', '2023-03-25']}) # 转换为datetime对象[^3] df['datetime'] = pd.to_datetime(df['date_str']) ``` 转换后列的dtype会变为`datetime64[ns]`,支持时间序列操作如重采样(resample)或时间差计算。 2. **处理特殊格式** 若日期字符串格式非标准(如`dd/mm/yyyy`),需指定`format`参数: ```python df['datetime'] = pd.to_datetime(df['date_str'], format='%d/%m/%Y') ``` 格式符号说明: - `%d`:日(01-31) - `%m`:月(01-12) - `%Y`:四位年份(如2023) - 完整格式符见Python官方文档 3. **错误处理** 当存在非法日期时,可通过`errors`参数控制行为: ```python # 将无效值转为NaT(Not a Time) df['datetime'] = pd.to_datetime(df['date_str'], errors='coerce') # 直接忽略错误(保留原字符串) df['datetime'] = pd.to_datetime(df['date_str'], errors='ignore') ``` 4. **读取时直接转换** 在数据加载阶段完成转换(如CSV文件): ```python df = pd.read_csv('data.csv', parse_dates=['date_column']) ``` ### 转换后的操作示例 ```python # 提取年份/月份 df['year'] = df['datetime'].dt.year df['month'] = df['datetime'].dt.month # 时间偏移(如加1天) df['next_day'] = df['datetime'] + pd.DateOffset(days=1) ``` ### 注意事项 - 若原始数据包含时区信息,转换时需通过`utc=True`参数处理 - 高频时间序列可通过`pd.tseries.frequencies`模块进行周期分析[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值