pandas 在panda Dataframe 中将带时间和不带时间的字符串(混合格式)转换为datetime

amrnrhlw  于 2023-02-02  发布在  其他
关注(0)|答案(1)|浏览(110)

使用astype函数将panda Dataframe 列从object转换为datetime时,根据字符串是否具有时间组件,行为会有所不同。转换列的正确方法是什么?

df = pd.DataFrame({'Date': ['12/07/2013 21:50:00','13/07/2013 00:30:00','15/07/2013','11/07/2013']})

df['Date'] = pd.to_datetime(df['Date'], format="%d/%m/%Y %H:%M:%S", exact=False, dayfirst=True, errors='ignore')

输出:

Date
0   12/07/2013 21:50:00
1   13/07/2013 00:30:00
2   15/07/2013
3   11/07/2013

但dtype仍为object。执行以下操作时:

df['Date'] = df['Date'].astype('datetime64')

它变为datetime dtype,但是第0和3行上的日和月未被正确解析。

Date
0   2013-12-07 21:50:00
1   2013-07-13 00:30:00
2   2013-07-15 00:00:00
3   2013-11-07 00:00:00

预期结果为:

Date
0   2013-07-12 21:50:00
1   2013-07-13 00:30:00
2   2013-07-15 00:00:00
3   2013-07-11 00:00:00
wfauudbj

wfauudbj1#

如果我们看一下源代码,如果您传递format=dayfirst=参数,dayfirst=将永远不会被读取,因为传递format=调用了C函数(np_datetime_strings.c),它不使用dayfirst=进行转换。另一方面,如果只传递dayfirst=,它将用于首先猜测格式,福尔斯再使用dateutil.parser.parse进行转换。因此,只使用其中一个。
在大多数情况下,

df['Date'] = pd.to_datetime(df['Date'])

完成任务。
在OP中的特定示例中,传递dayfirst=True就完成了任务。

df['Date'] = pd.to_datetime(df['Date'], dayfirst=True)

也就是说,传递format=会使转换速度提高25倍(更多信息请参见this post),因此,如果帧大于10k行,那么最好传递format=。现在,由于格式是混合的,一种方法是分两步执行转换(errors='coerce'参数会很有用)

  • 转换带有时间组件的日期时间
  • 用转换为不同格式的Series填充NaT值(“强制”行)。
df['Date'] = pd.to_datetime(df['Date'], format='%d/%m/%Y %H:%M:%S', errors='coerce')
df['Date'] = df['Date'].fillna(pd.to_datetime(df['Date'], format='%d/%m/%Y', errors='coerce'))

这种方法(执行或多次转换)可用于转换任何日期时间格式“古怪”的列。

相关问题