将具有多个时区的pandas列转换为单个时区

时间:2019-05-21 19:14:24

标签: python python-3.x pandas dataframe timezone

问题

我在pandas DataFrame中有一列,其中包含带有时区的时间戳。本专栏中有两个不同的时区,我需要确保只有一个。这是该列末尾的输出:

260003    2019-05-21 12:00:00-06:00
260004    2019-05-21 12:15:00-06:00
Name: timestamp, Length: 260005, dtype: object

对于价值而言,时间戳记在-06:00-07:00之间变化,并具有以下输出:

datetime.datetime(2007, 10, 1, 1, 0, tzinfo=tzoffset(None, -21600)) for -06:00 datetime.datetime(2007, 11, 17, 5, 15, tzinfo=tzoffset(None, -25200))的{​​{1}}

我做了什么

我一直在尝试使用过去运行良好的tz.localize和tz.convert,但我想数据只有一个时区。例如,如果我这样做:

-07:00

我得到:

df['timestamp'].dt.tz_localize('MST', ambiguous='infer').dt.tz_convert('MST')

问题

是否可以将它们转换为MST?还是任何时区,真的吗?我想我可以按时区分解DataFrame(不确定100%如何做到,但我想有可能)并对其进行处理,但我想问一下是否有更聪明的解决方案。谢谢!

3 个答案:

答案 0 :(得分:2)

我尝试过:

df = pd.DataFrame({'timestamp':['2019-05-21 12:00:00-06:00',
                                '2019-05-21 12:15:00-07:00']})
df['timestamp'] = pd.to_datetime(df.timestamp)

df.timestamp.dt.tz_localize('MST')

工作正常,并给出:

0   2019-05-21 18:00:00-07:00
1   2019-05-21 19:15:00-07:00
Name: timestamp, dtype: datetime64[ns, MST]

这不是您所期望的吗?


编辑:感谢@ G.Anderson的评论,我尝试了带有时区感知时间戳的不同数据:

df = pd.DataFrame({'timestamp':[pd.to_datetime('2019-05-21 12:00:00').tz_localize('MST'),
                         pd.to_datetime('2019-05-21 12:15:00').tz_localize('EST')]})

然后

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

给出相同的错误。然后我添加了utc=True

df.timestamp = pd.to_datetime(df.timestamp, utc=True)

# df.timestamp
# 0   2019-05-21 19:00:00+00:00
# 1   2019-05-21 17:15:00+00:00
# Name: timestamp, dtype: datetime64[ns, UTC]

df.timestamp.dt.tz_convert('MST')

工作正常,并给出:

0   2019-05-21 12:00:00-07:00
1   2019-05-21 10:15:00-07:00
Name: timestamp, dtype: datetime64[ns, MST]

答案 1 :(得分:1)

# input data
import pandas as pd
series = pd.Series(data=
    [pd.to_datetime('2019-01-01 00:00:00').tz_localize('MST'),
     pd.to_datetime('2019-01-01 01:10:00').tz_localize('UTC')])
print(series)

给予

0    2019-01-01 00:00:00-07:00
1    2019-01-01 01:10:00+00:00
dtype: object

确实

series.dt.tz_convert('MST')

给出“ ValueError:数组必须全部在相同的时区” “ ValueError:知道Tz的datetime.datetime不能转换为datetime64,除非utc = True” 。因此,似乎您必须以非矢量化方式进行操作:

new_series = pd.Series(index=series.index,
    data=[x.tz_convert('MST') for x in series])
print(new_series)

给予

0   2019-01-01 00:00:00-07:00
1   2018-12-31 18:10:00-07:00
dtype: datetime64[ns, MST]

编辑:如果@QuangHoang是正确的(即“该选项自动将时间戳本地化为utc” ,请仔细检查!)有关pd.to_datetime(..., utc=True)的含义,那么以下解决方案将也可以:

new_series = pd.to_datetime(series, utc=True).dt.tz_convert('MST')
print(new_series)

给予

0   2019-01-01 00:00:00-07:00
1   2018-12-31 18:10:00-07:00
dtype: datetime64[ns, MST]

答案 2 :(得分:1)

我们有一系列a,其中包含多个不同的时区。 我们期望a.tz_convert()a.tz_localize()可以工作,但不能。 解决方案是使用apply方法。 请参见以下示例:

> a
0    2019-10-04 16:30:00+02:00
1    2019-10-07 16:00:00-04:00
2    2019-09-24 08:30:00-07:00
Name: localized, dtype: object

> a.iloc[0]
Timestamp('2019-10-04 16:30:00+0200', tz='Europe/Amsterdam')

> a.apply(lambda x: x.tz_convert('America/Los_Angeles'))
0   2019-10-04 07:30:00-07:00
1   2019-10-07 13:00:00-07:00
2   2019-09-24 08:30:00-07:00
Name: localized, dtype: datetime64[ns, America/Los_Angeles]

# Make it tz-naive, i.e. remove tz info, note you lose information here, you might want to store tz-info in another series before the conversion.
> a.apply(lambda x: x.tz_localize(None))
0   2019-10-04 16:30:00
1   2019-10-07 16:00:00
2   2019-09-24 08:30:00
Name: localized, dtype: datetime64[ns]