首页 > 解决方案 > 将 Tz 感知 datetime.datetime 转换为 datetime64/DatetimeIndex/Timestamp

问题描述

我正在使用 PostgreSQL 数据库来存储和检索数据。我得到的列是:

  1. date : 带时区的时间戳
  2. 值:双精度
  3. 类型:字符变化(数据的近似地理位置)
  4. 代码:字符变化(与确切地理位置相关的代码)

这就是我使用以下方式获取数据的方式pd.read_sql_query

df     = pd.read_sql_query("SELECT date, value FROM my_db WHERE code ='%s' and type = '%s' and date >= '%s' and date <= '%s' ORDER BY date;"
                            % (code, type, start_date, end_date), con=Cdc.engine, index_col="date")
df["value"].replace(to_replace=0, value=np.nan, inplace=True)  # replace 0 by NaN since 0 is an error in my data

然后我尝试执行以下操作,这就是我得到错误的地方:

df = df[df.index.month.isin(wanted_month)]

这返回了我的错误:

AttributeError: 'Index' object has no attribute 'month'

1.我试图通过这样做来解决这个问题:

self.df_cdc.index = pd.to_datetime(self.df_cdc.index)

但它不起作用,因为我收到此错误:

ValueError: Array must be all same time zone
During handling of the above exception, another exception occurred:
ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True

2.我也尝试过:

df = df[df.index.dt.month.isin(wanted_month)]

但我得到这个错误:

AttributeError: 'Index' object has no attribute 'dt'

这是我的 DF 的索引值的示例:

#   2019-12-30 21:10:00+01:00 --> <class 'datetime.datetime'>
#   2019-10-11 15:00:00+02:00 --> <class 'datetime.datetime'>

这些是法国数据,因此与 UTC 相比,我们有夏令时,冬季 +1 小时,夏季 +2 小时(例如:)winter: UTC = 10h00 --> France = 11h00; summer: UTC = 10h00 --> France = 12h00

显示 tzinfo 给了我这个:

print(df.index[0], "-->", df.index[0].tzinfo)
print(df.index[15000], "-->", df.index[15000].tzinfo
2019-01-01 00:00:00+01:00 --> psycopg2.tz.FixedOffsetTimezone(offset=60, name=None)
2019-04-15 05:00:00+02:00 --> psycopg2.tz.FixedOffsetTimezone(offset=120, name=None)

感谢您的关注。

编辑:我找到了解决方案并将其发布在下面。

标签: pythonpython-3.xpandaspostgresql

解决方案


我通过先转换为 UTC,然后再转换回我的时区来解决问题(我已验证并且日期和时间是正确的:

    df.index = pd.to_datetime(self.df_cdc.index, utc=True)
    df.index = self.df_cdc.index.tz_convert("Europe/Paris")

这是完整的查询:

df     = pd.read_sql_query("SELECT date, value FROM my_db WHERE code ='%s' and type = '%s' and date >= '%s' and date <= '%s' ORDER BY date;"
                                % (code, type, start_date, end_date), con=Cdc.engine, index_col="date")
df["value"].replace(to_replace=0, value=np.nan, inplace=True)  # replace 0 by NaN since 0 is an error in my data
df.index = pd.to_datetime(self.df_cdc.index, utc=True)
df.index = self.df_cdc.index.tz_convert("Europe/Paris")

推荐阅读