0

0

Pandas中合并日期与时间列以避免转换错误

碧海醫心

碧海醫心

发布时间:2025-11-18 13:14:20

|

392人浏览过

|

来源于php中文网

原创

pandas中合并日期与时间列以避免转换错误

在Pandas中将单独的日期和时间字符串列转换为`datetime`类型时,如果时间列不包含日期信息,`pd.to_datetime`默认会填充当前系统日期,导致日期部分被意外更改。本文将详细介绍如何通过字符串拼接或更推荐的日期时间与时间差组合方式,正确地将分散的日期和时间信息合并为一个完整的`datetime`对象,确保数据转换的准确性。

理解日期时间转换中的常见陷阱

在使用Pandas处理时间序列数据时,经常会遇到日期和时间信息存储在不同的列中的情况。例如,一个DataFrame可能包含一个order_date列(仅日期)和一个order_time列(仅时间)。当尝试将这些列转换为标准的datetime对象时,如果不采取正确的策略,可能会导致数据不一致。

考虑以下初始DataFrame:

import pandas as pd

data = {
    'order_details_id': [1, 2, 3, 4, 5],
    'order_id': [1, 2, 2, 2, 2],
    'order_date': ['1/1/23', '1/1/23', '1/1/23', '1/1/23', '1/1/23'],
    'order_time': ['11:38:36 AM', '11:57:40 AM', '11:57:40 AM', '11:57:40 AM', '11:57:40 AM'],
    'item_id': [109.0, 108.0, 124124.0, 117.0, 129.0]
}
df = pd.DataFrame(data)
print("原始DataFrame:")
print(df)
print("\n原始数据类型:")
print(df.dtypes)

输出:

原始DataFrame:
   order_details_id  order_id order_date   order_time  item_id
0                 1         1     1/1/23  11:38:36 AM    109.0
1                 2         2     1/1/23  11:57:40 AM    108.0
2                 3         2     1/1/23  11:57:40 AM    124124.0
3                 4         2     1/1/23  11:57:40 AM    117.0
4                 5         2     1/1/23  11:57:40 AM    129.0

原始数据类型:
order_details_id      int64
order_id              int64
order_date           object
order_time           object
item_id             float64
dtype: object

如果尝试单独转换order_date和order_time列,会发现order_time列在转换为datetime类型后,其日期部分被意外地更改为当前系统日期。

# 错误示范:单独转换时间列
df_copy = df.copy()
df_copy['order_date'] = pd.to_datetime(df_copy['order_date'])
df_copy['order_time'] = pd.to_datetime(df_copy['order_time'])
print("\n错误转换后的DataFrame (order_time日期被改变):")
print(df_copy)

输出(order_time的日期部分会显示为你运行代码时的日期,例如2023-12-29):

错误转换后的DataFrame (order_time日期被改变):
   order_details_id  order_id  order_date          order_time  item_id
0                 1         1  2023-01-01   2023-12-29 11:38:36    109.0
1                 2         2  2023-01-01   2023-12-29 11:57:40    108.0
2                 3         2  2023-01-01   2023-12-29 11:57:40    124124.0
3                 4         2  2023-01-01   2023-12-29 11:57:40    117.0
4                 5         2  2023-01-01   2023-12-29 11:57:40    129.0

原因分析:order_time列的字符串(如"11:38:36 AM")仅包含时间信息,不包含日期。当pd.to_datetime函数在没有明确日期信息的情况下处理此类字符串时,它会默认使用当前系统日期来填充缺失的日期部分。这通常不是我们期望的行为,因为我们希望保留order_date列提供的原始日期。

正确合并日期与时间的方法

为了避免上述问题,我们应该在将数据转换为datetime类型之前,将日期和时间信息合并在一起。以下是几种推荐的方法。

方法一:字符串拼接后进行转换

最直观的方法是将order_date和order_time两列的字符串内容拼接成一个新的字符串列,然后对这个新列应用pd.to_datetime。

df_method1 = df.copy()
df_method1['order_datetime'] = pd.to_datetime(df_method1['order_date'].str.cat(df_method1['order_time'], sep=' '))
print("\n方法一:字符串拼接后转换:")
print(df_method1)
print("\n方法一:数据类型检查:")
print(df_method1.dtypes)

输出:

方法一:字符串拼接后转换:
   order_details_id  order_id order_date   order_time  item_id      order_datetime
0                 1         1     1/1/23  11:38:36 AM    109.0 2023-01-01 11:38:36
1                 2         2     1/1/23  11:57:40 AM    108.0 2023-01-01 11:57:40
2                 3         2     1/1/23  11:57:40 AM    124124.0 2023-01-01 11:57:40
3                 4         2     1/1/23  11:57:40 AM    117.0 2023-01-01 11:57:40
4                 5         2     1/1/23  11:57:40 AM    129.0 2023-01-01 11:57:40

方法一:数据类型检查:
order_details_id             int64
order_id                     int64
order_date                  object
order_time                  object
item_id                    float64
order_datetime      datetime64[ns]
dtype: object

这种方法简单易懂,通过在日期和时间之间添加一个空格进行拼接,pd.to_datetime能够识别并正确解析。

FreeTTS
FreeTTS

FreeTTS是一个免费开源的在线文本到语音生成解决方案,可以将文本转换成MP3,

下载

方法二:日期时间与时间差组合(推荐)

这种方法更为健壮和推荐,它将order_date转换为datetime对象,将order_time转换为timedelta(时间差)对象,然后将两者相加。这种方式避免了字符串操作可能带来的格式问题,并且在语义上更清晰。

df_method2 = df.copy()
# 将order_date转换为datetime类型
df_method2['order_date_dt'] = pd.to_datetime(df_method2['order_date'])
# 将order_time转换为timedelta类型
df_method2['order_time_td'] = pd.to_timedelta(df_method2['order_time'])

# 将datetime和timedelta相加
df_method2['order_datetime'] = df_method2['order_date_dt'] + df_method2['order_time_td']

# 可以选择删除中间列
df_method2 = df_method2.drop(columns=['order_date_dt', 'order_time_td'])

print("\n方法二:日期时间与时间差组合:")
print(df_method2)
print("\n方法二:数据类型检查:")
print(df_method2.dtypes)

为了更简洁,可以直接在赋值时使用pop()方法,这样可以同时删除原始列:

df_method2_pop = df.copy()
df_method2_pop['order_datetime'] = pd.to_datetime(df_method2_pop.pop('order_date')) + pd.to_timedelta(df_method2_pop.pop('order_time'))
print("\n方法二(使用pop()):日期时间与时间差组合:")
print(df_method2_pop)
print("\n方法二(使用pop()):数据类型检查:")
print(df_method2_pop.dtypes)

输出与方法一类似,但数据处理过程更为类型安全:

方法二:日期时间与时间差组合:
   order_details_id  order_id  item_id      order_datetime
0                 1         1    109.0 2023-01-01 11:38:36
1                 2         2    108.0 2023-01-01 11:57:40
2                 3         2    124124.0 2023-01-01 11:57:40
3                 4         2    117.0 2023-01-01 11:57:40
4                 5         2    129.0 2023-01-01 11:57:40

方法二:数据类型检查:
order_details_id             int64
order_id                     int64
item_id                    float64
order_datetime      datetime64[ns]
dtype: object

这种方法不仅解决了日期被更改的问题,还提供了更清晰的数据类型转换路径:日期字符串转换为日期时间,时间字符串转换为时间差,然后相加得到完整的日期时间。

方法三:优化数据读取(如果可能)

如果数据源允许,最理想的情况是在数据导入时就将日期和时间作为一个整体字符串来读取。这样可以简化后续的转换步骤。

假设原始数据已经被预处理成如下格式:

data_combined = {
    'order_details_id': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
    'order_id': {0: 1, 1: 2, 2: 2, 3: 2, 4: 2},
    'order_date_time': {0: '1/1/23 11:38:36 AM',
                        1: '1/1/23 11:57:40 AM',
                        2: '1/1/23 11:57:40 AM',
                        3: '1/1/23 11:57:40 AM',
                        4: '1/1/23 11:57:40 AM'},
    'item_id': {0: 109.0, 1: 108.0, 2: 124124.0, 3: 117.0, 4: 129.0}
}
df_combined = pd.DataFrame(data_combined)
print("\n方法三:初始数据已合并日期时间:")
print(df_combined)

df_combined['order_dt'] = pd.to_datetime(df_combined['order_date_time'])
print("\n方法三:直接转换合并列:")
print(df_combined)
print("\n方法三:数据类型检查:")
print(df_combined.dtypes)

输出:

方法三:初始数据已合并日期时间:
   order_details_id  order_id     order_date_time  item_id
0                 1         1  1/1/23 11:38:36 AM    109.0
1                 2         2  1/1/23 11:57:40 AM    108.0
2                 3         2  1/1/23 11:57:40 AM    124124.0
3                 4         2  1/1/23 11:57:40 AM    117.0
4                 5         2  1/1/23 11:57:40 AM    129.0

方法三:直接转换合并列:
   order_details_id  order_id     order_date_time  item_id            order_dt
0                 1         1  1/1/23 11:38:36 AM    109.0 2023-01-01 11:38:36
1                 2         2  1/1/23 11:57:40 AM    108.0 2023-01-01 11:57:40
2                 3         2  1/1/23 11:57:40 AM    124124.0 2023-01-01 11:57:40
3                 4         2  1/1/23 11:57:40 AM    117.0 2023-01-01 11:57:40
4                 5         2  1/1/23 11:57:40 AM    129.0 2023-01-01 11:57:40

方法三:数据类型检查:
order_details_id             int64
order_id                     int64
order_date_time             object
item_id                    float64
order_dt            datetime64[ns]
dtype: object

这种方法最为简洁,因为pd.to_datetime可以直接处理包含完整日期和时间信息的字符串。

注意事项

  • 明确数据来源:在进行日期时间转换前,务必了解原始数据中日期和时间的存储方式。是单独存储,还是已经合并?
  • 格式参数:如果日期时间字符串的格式不标准或不一致,可以使用pd.to_datetime的format参数明确指定解析格式,例如 pd.to_datetime(series, format='%Y-%m-%d %H:%M:%S')。这有助于提高解析效率和准确性,尤其是在处理大量数据时。
  • 错误处理:pd.to_datetime的errors参数可以控制如何处理解析错误。'coerce'会将无法解析的值转换为NaT(Not a Time),而'raise'(默认)则会抛出错误。
  • 性能考量:对于大型数据集,字符串拼接(方法一)可能比timedelta方法(方法二)略慢,因为涉及到更多的字符串操作。方法二通过数值运算(datetime + timedelta)通常效率更高。

总结

在Pandas中处理分散的日期和时间列时,直接将不含日期信息的时间字符串转换为datetime类型会导致日期部分被当前系统日期覆盖。为了确保数据转换的准确性,推荐以下策略:

  1. 将日期和时间字符串拼接成一个完整的日期时间字符串,然后使用pd.to_datetime进行转换。
  2. 将日期列转换为datetime对象,将时间列转换为timedelta对象,然后将两者相加得到最终的datetime对象。 这种方法在类型安全性和性能方面通常更优。
  3. 如果数据源允许,在数据导入阶段就将日期和时间合并为一个字段,后续直接转换。

通过采用这些方法,您可以有效地管理和转换时间序列数据,避免常见的日期时间处理陷阱,确保数据分析的准确性和可靠性。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

51

2025.12.04

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

299

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

617

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

430

2024.06.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

253

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1463

2023.10.24

c++主流开发框架汇总
c++主流开发框架汇总

本专题整合了c++开发框架推荐,阅读专题下面的文章了解更多详细内容。

25

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号