Pandas 将 'timestamp without timezones' 列解释为不同的类型

Pandas interprets 'timestamp without timezones' columns as different types

我读了 table pandas:

import pandas as pd
import numpy as np
con = psycopg2.connect(...)
mframe = pd.read_sql('''select dt_A, dt_B from (...)''',con)

数据库中的两列(dt_A 和 dt_B)都是 'timestamp without timezone' 类型。但是,pandas:

将它们读取为不同的类型
mframe.dt_A.dtype,  mframe.dt_B.dtype

产量:

(dtype('O'), dtype('<M8[ns]'))

我能够强制将两列都识别为

"<M8[ns]"

使用 'parse_dates' 参数,但我想了解导致此问题的原因。据我检查,两列都不包含任何“Na”(这是我的第一个怀疑)。什么情况下它们会被不同地解释?

更新: 我正在使用 Pandas 版本 0.15.1;我可以使用 sqlalchemypsycopg2 连接重现该问题。

更新 2:运行 带有小 limit 的原始查询按我预期的方式工作——也就是说,两列具有相同的数据类型 "M8[ns]"。仍然不确定是哪种条目(格式错误的东西?)导致了这种情况,但我现在很满意。

更新 3:joris 知道了。请参阅下面的评论。

正如您所指出的,它在限制某些数据(将 LIMIT 5 添加到您的查询中)时可以正常工作,它可能与日期中的某些 'incorrect' 值有关。
要找出导致问题的值,您可以读入所有数据(产生对象 dtype),然后使用以下命令手动进行转换:

pd.to_datetime(column, errors='raise')

errors='raise' 将确保您收到一条错误消息,指示无法转换的日期。

要确保将列转换为 datetime64 值,而不考虑无效值,您应该在 parse_dates kwarg 中指定列。


似乎在使用read_sql_table时,无效日期会自动转换为NaT,而read_sql_query会将值保留为datetime.datetime值。我为这种不一致打开了一个问题:https://github.com/pydata/pandas/issues/9261