为了账号安全,请及时绑定邮箱和手机立即绑定

如何将包含 Excel 序列日期和常规日期的列转换为 pandas 日期时间?

如何将包含 Excel 序列日期和常规日期的列转换为 pandas 日期时间?

缥缈止盈 2023-08-22 14:54:11
我有一个数据框,其中的生日具有与 Excel 序列日期混合的常规日期,如下所示:09/01/2020 12:00:00 AM05/15/1985 12:00:00 AM06/07/2013 12:00:00 AM332332629929428我尝试了此答案中的解决方案,所有 Excel 串行格式的日期都被清空,同时保留正常日期格式的日期。这是我的代码:import pandas as pdimport xlrdimport numpy as npfrom numpy import *from numpy.core import *import osimport datetimefrom datetime import datetime, timedeltaimport globdef from_excel_ordinal(ordinal, _epoch0=datetime(1899, 12, 31)):    if ordinal >= 60:        ordinal -= 1  # Excel leap year bug, 1900 is not a leap year!    return (_epoch0 + timedelta(days=ordinal)).replace(microsecond=0)path = 'C:\\Input'os.chdir(path)filelist = glob.glob('*BLAH*.xlsx')  filename = os.fsdecode(filelist[0])df = pd.read_excel(filename, sheet_name = 'Blah Blah') m = df['Birthday'].astype(str).str.isdigit()df.loc[m, 'Birthday'] = df.loc[m, 'Birthday'].astype(int).apply(from_excel_ordinal)df['Birthday'] = pd.to_datetime(df['Birthday'], errors = 'coerce')我不确定我在哪里出了问题,因为代码不应该像现在这样清空生日。
查看完整描述

2 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

  • 无法以相同的方式解析所有日期

  • 加载数据框

  • 如果尚未将该dates列转换为 a,则将其转换为 a。str

  • 使用布尔索引选择不同的日期类型

    • 假设常规日期包含/

    • 假设 Excel 序列日期不包含/

  • 根据日期时间类型分别修复每个数据帧

  • 将数据帧重新连接在一起。

import pandas as pd

from datetime import datetime


# load data

df = pd.DataFrame({'dates': ['09/01/2020', '05/15/1985', '06/07/2013', '33233', '26299', '29428']})


# display(df)


        dates

0  09/01/2020

1  05/15/1985

2  06/07/2013

3       33233

4       26299

5       29428


# set the column type as a str if it isn't already

df.dates = df.dates.astype('str')


# create a date mask based on the string containing a /

date_mask = df.dates.str.contains('/')


# split the dates out for excel

df_excel = df[~date_mask].copy()


# split the regular dates out

df_reg = df[date_mask].copy()


# convert reg dates to datetime

df_reg.dates = pd.to_datetime(df_reg.dates)


# convert excel dates to datetime; the column needs to be cast as ints

df_excel.dates = pd.TimedeltaIndex(df_excel.dates.astype(int), unit='d') + datetime(1900, 1, 1)


# combine the dataframes

df = pd.concat([df_reg, df_excel])

显示(df)

       dates

0 2020-09-01

1 1985-05-15

2 2013-06-07

3 1990-12-28

4 1972-01-03

5 1980-07-28


查看完整回答
反对 回复 2023-08-22
?
侃侃无极

TA贡献2051条经验 获得超10个赞

pd.TimedeltaIndex(dates_in_excel_serial_format, 单位='d') + pd.datetime(1900,1,1)


演示:


> dates_in_excel_serial_format = [29428]

> pd.TimedeltaIndex(dates_in_excel_serial_format, unit='d') + pd.datetime(1900,1,1)

< DatetimeIndex(['1980-07-28'], dtype='datetime64[ns]', freq=None)


查看完整回答
反对 回复 2023-08-22
  • 2 回答
  • 0 关注
  • 1627 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信