当时区不同时是 pandas 数据帧,如何更改时区?

When time zones are different is a pandas dataframe, how to change time zone?

我得到了这样一个数据框:

   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' 是时区列中的内容。

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

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 操作。

.dt.tz_convert 仅适用于一个时区,因此您必须这样做 row-by-row。但是,比这更有效的方法是按 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

你(几乎)不能这样做,因为 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 访问器,所以你必须单独访问值而不是以向量化的方式。