
在Pandas中将单独的日期和时间字符串列转换为`datetime`类型时,如果时间列不包含日期信息,`pd.to_datetime`默认会填充当前系统日期,导致日期部分被意外更改。本文将详细介绍如何通过字符串拼接或更推荐的日期时间与时间差组合方式,正确地将分散的日期和时间信息合并为一个完整的`datetime`对象,确保数据转换的准确性。
理解日期时间转换中的常见陷阱
在使用Pandas处理时间序列数据时,经常会遇到日期和时间信息存储在不同的列中的情况。例如,一个DataFrame可能包含一个order_date列(仅日期)和一个order_time列(仅时间)。当尝试将这些列转换为标准的datetime对象时,如果不采取正确的策略,可能会导致数据不一致。
考虑以下初始DataFrame:
import pandas as pddata = { '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, 124.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_id0 1 1 1/1/23 11:38:36 AM 109.01 2 2 1/1/23 11:57:40 AM 108.02 3 2 1/1/23 11:57:40 AM 124.03 4 2 1/1/23 11:57:40 AM 117.04 5 2 1/1/23 11:57:40 AM 129.0原始数据类型:order_details_id int64order_id int64order_date objectorder_time objectitem_id float64dtype: 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_id0 1 1 2023-01-01 2023-12-29 11:38:36 109.01 2 2 2023-01-01 2023-12-29 11:57:40 108.02 3 2 2023-01-01 2023-12-29 11:57:40 124.03 4 2 2023-01-01 2023-12-29 11:57:40 117.04 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_datetime0 1 1 1/1/23 11:38:36 AM 109.0 2023-01-01 11:38:361 2 2 1/1/23 11:57:40 AM 108.0 2023-01-01 11:57:402 3 2 1/1/23 11:57:40 AM 124.0 2023-01-01 11:57:403 4 2 1/1/23 11:57:40 AM 117.0 2023-01-01 11:57:404 5 2 1/1/23 11:57:40 AM 129.0 2023-01-01 11:57:40方法一:数据类型检查:order_details_id int64order_id int64order_date objectorder_time objectitem_id float64order_datetime datetime64[ns]dtype: object
这种方法简单易懂,通过在日期和时间之间添加一个空格进行拼接,pd.to_datetime能够识别并正确解析。
方法二:日期时间与时间差组合(推荐)
这种方法更为健壮和推荐,它将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_datetime0 1 1 109.0 2023-01-01 11:38:361 2 2 108.0 2023-01-01 11:57:402 3 2 124.0 2023-01-01 11:57:403 4 2 117.0 2023-01-01 11:57:404 5 2 129.0 2023-01-01 11:57:40方法二:数据类型检查:order_details_id int64order_id int64item_id float64order_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: 124.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_id0 1 1 1/1/23 11:38:36 AM 109.01 2 2 1/1/23 11:57:40 AM 108.02 3 2 1/1/23 11:57:40 AM 124.03 4 2 1/1/23 11:57:40 AM 117.04 5 2 1/1/23 11:57:40 AM 129.0方法三:直接转换合并列: order_details_id order_id order_date_time item_id order_dt0 1 1 1/1/23 11:38:36 AM 109.0 2023-01-01 11:38:361 2 2 1/1/23 11:57:40 AM 108.0 2023-01-01 11:57:402 3 2 1/1/23 11:57:40 AM 124.0 2023-01-01 11:57:403 4 2 1/1/23 11:57:40 AM 117.0 2023-01-01 11:57:404 5 2 1/1/23 11:57:40 AM 129.0 2023-01-01 11:57:40方法三:数据类型检查:order_details_id int64order_id int64order_date_time objectitem_id float64order_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类型会导致日期部分被当前系统日期覆盖。为了确保数据转换的准确性,推荐以下策略:
将日期和时间字符串拼接成一个完整的日期时间字符串,然后使用pd.to_datetime进行转换。将日期列转换为datetime对象,将时间列转换为timedelta对象,然后将两者相加得到最终的datetime对象。 这种方法在类型安全性和性能方面通常更优。如果数据源允许,在数据导入阶段就将日期和时间合并为一个字段,后续直接转换。
通过采用这些方法,您可以有效地管理和转换时间序列数据,避免常见的日期时间处理陷阱,确保数据分析的准确性和可靠性。
以上就是Pandas中合并日期与时间列以避免转换错误的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1380848.html
微信扫一扫
支付宝扫一扫