【问题标题】:When time zones are different is a pandas dataframe, how to change time zone?当时区不同时是熊猫数据框,如何更改时区?
【发布时间】:2022-02-02 17:20:44
【问题描述】:

我有一个这样的数据框:

   State   Timezone    UTC_Time               Parking
0  OH      US/Eastern  2019-01-01 12:00:00    12
1  OH      US/Eastern  2019-01-01 13:00:00    11
2  WI      US/Central  2019-01-01 12:00:00    65
3  WI      US/Central  2019-01-01 13:00:00    67

我想通过 dt.tz_convert('XXX') 添加一列“Local_Time”,其中“XXX”是 Timezone 列中的内容。

以前只有俄亥俄州的数据我可以简单地使用

df['Local_Time'] = df['UTC_Time'].dt.tz_convert('US/Eastern')

我试过了

df['Local_Time'] = df['UTC_Time'].dt.tz_convert(df['Timezone'])

但因 ValueError 失败:Series 的真值不明确。我想后面还有其他 numpy 操作。

【问题讨论】:

    标签: pandas dataframe numpy datetime timezone


    【解决方案1】:

    您(几乎)不能这样做,因为pd.DatetimeIndex 仅支持一个时区,但您可以在Series 中拥有多个pd.Timestamp 实例。您在这里丢失的是 dt 访问器,因为您的 dtype 列将是 object 而不是 datetime64

    df['Local_Time'] = df.apply(lambda x: x['UTC_Time'].tz_localize(x['Timezone']), axis=1)
    print(df)
    
    # Output
      State    Timezone             UTC_Time  Parking                 Local_Time
    0    OH  US/Eastern  2019-01-01 12:00:00       12  2019-01-01 12:00:00-05:00
    1    OH  US/Eastern  2019-01-01 13:00:00       11  2019-01-01 13:00:00-05:00
    2    WI  US/Central  2019-01-01 12:00:00       65  2019-01-01 12:00:00-06:00
    3    WI  US/Central  2019-01-01 13:00:00       67  2019-01-01 13:00:00-06:00
    

    检查数据类型:

    >>> df.dtypes
    State                 object
    Timezone              object
    UTC_Time      datetime64[ns]
    Parking                int64
    Local_Time            object
    dtype: object
    

    您必须知道,将多个时区放入同一个系列中完全不是最佳选择,主要是因为您丢失了 dt 访问器,因此您必须单独访问值,而不是以矢量化方式。

    【讨论】:

    • 感谢您的回复。我去了 pandas.Series.dt.tz_convert 的情况说明书,但仍然没有得到它。只是粗略的猜测,这可能是因为函数本身的机制。这里你的解释很有用!
    • tz_convert 将具有原始时区的 DatetimeIndex 转换为另一个时区,并且只有一个时区。另一方面,tz_localize 将一个天真的 DatetimeIndex(没有指示 tz)转换为本地日期时间:它不会更改日期时间的值,只需将时区附加到日期。
    • ? 哦,这更有意义,谢谢!
    【解决方案2】:

    .dt.tz_convert 仅适用于经过一个时区,因此您必须逐行执行此操作。但是,比这更有效的方法是按 Timezone 分组,并在该组的所有 UTC_Time 值上为每个组调用 tz_convert

    df['Local_Time'] = df.groupby('Timezone', as_index=False).apply(lambda g: g['UTC_Time'].dt.tz_convert(g['Timezone'].iloc[0])).reset_index(drop=True)
    

    输出:

    >>> df
      State    Timezone                  UTC_Time  Parking                 Local_Time
    0    OH  US/Eastern 2019-01-01 12:00:00+00:00       12  2019-01-01 06:00:00-06:00
    1    OH  US/Eastern 2019-01-01 13:00:00+00:00       11  2019-01-01 07:00:00-06:00
    2    WI  US/Central 2019-01-01 12:00:00+00:00       65  2019-01-01 07:00:00-05:00
    3    WI  US/Central 2019-01-01 13:00:00+00:00       67  2019-01-01 08:00:00-05:00
    

    【讨论】:

    • 嗨@richardec。请问df['Local_Time].dtype 的输出是什么?
    • 嗯,@Corralien df['Local_Time'].dtypedtype('O'),但 df['UTC_Time'].dtypedatetime64[ns, UTC]
    • 好的。谢谢你的回答。
    • 所以你丢失了dt 访问器。检查我的答案:) 这不是一个可解决的问题。这就是UTC存在的原因。大声笑。
    • 嗯,df['Local_Time'].astype(df['UTC_Time'].dtype) 不起作用:ValueError: Tz-aware datetime.datetime cannot be converted to datetime64 unless utc=True
    猜你喜欢
    • 2021-04-03
    • 2022-01-10
    • 2016-05-26
    • 2017-09-09
    • 1970-01-01
    • 2017-05-18
    • 2018-02-20
    • 1970-01-01
    相关资源
    最近更新 更多