如何将具有不同时区的 tz_convert 应用于熊猫数据框中的不同行

Posted

技术标签:

【中文标题】如何将具有不同时区的 tz_convert 应用于熊猫数据框中的不同行【英文标题】:How to apply tz_convert with different timezones to different rows in pandas dataframe 【发布时间】:2016-01-04 05:12:33 【问题描述】:

我正在尝试根据标准为 Pandas 数据框中的不同行设置不同的时区。作为 MWE,这是我尝试过的:

test = pd.DataFrame( data = pd.to_datetime(['2015-03-30 20:12:32','2015-03-12 00:11:11']) ,columns=['time'] )
test['new_col']=['new','old']
test.time=test.set_index('time').index.tz_localize('UTC')
test.loc[test.new_col=='new','time']=test[test.new_col=='new'].set_index('time').index.tz_convert('US/Pacific')
print test

这个的输出:

                        time new_col
0        1427746352000000000     new
1  2015-03-12 00:11:11+00:00     old

如您所见,更新时区的行被转换为整数。我怎样才能正确地做到这一点,以便更新的条目是日期时间?

【问题讨论】:

一列中不可能有不同的时区(列是同类类型的) 这似乎不是真的,请看下面的例子。 是的,但正如@jreback 解释的那样,您不再有日期时间列,而是一个对象列(原则上可以包含任何内容),失去了很多有用的功能 【参考方案1】:

使用 0.17.0rc2(0.17.0 于 10 月 9 日发布),您可以执行此操作。

In [43]: test['new_col2'] = [Timestamp('2015-03-30 20:12:32',tz='US/Eastern'),Timestamp('2015-03-30 20:12:32',tz='US/Pacific')]

In [44]: test
Out[44]: 
                       time new_col                   new_col2
0 2015-03-30 20:12:32+00:00     new  2015-03-30 20:12:32-04:00
1 2015-03-12 00:11:11+00:00     old  2015-03-30 20:12:32-07:00

In [45]: test.dtypes
Out[45]: 
time        datetime64[ns, UTC]
new_col                  object
new_col2                 object
dtype: object

请注意,混合时区列中强制object dtype。所以可以这样做,但一般不推荐。您需要单独更改条目。

您几乎总是单个时区的单个 dtyped 列。

【讨论】:

我错过了 Pandas 将混合时区列转换为 dtype object。但是,当我将时间设置为索引时(例如test[test.new_col=='new'].set_index('time').index),实际上我确实得到了一个 DatetimeIndex。但是,当我尝试将它分配回原始列时,它变成了乱码。你能解释一下为什么我会期待这种行为吗? 在 0.16.2 中这是一个错误,在 0.17.0 中会引发,请参阅 here【参考方案2】:

添加指定要转换到的时区的列后,这是一个有效的解决方案。

utc_df = pd.DataFrame("timestamp": [pd.Timestamp("2019-09-01 12:00:00+0000", tz="UTC"),
                                     pd.Timestamp("2019-11-01 12:00:00+0000", tz="UTC")],
                        "timezone": ["Europe/Brussels", "Europe/London"])

这个示例仍然有 UTC 时间,看起来像:

                  timestamp         timezone 
0 2019-09-01 12:00:00+00:00  Europe/Brussels 
1 2019-11-01 12:00:00+00:00    Europe/London

然后我们按时区分组并应用转换。

def localize_time(df):
    def convert_tz(tz_df):
        return tz_df.set_index('timestamp').tz_convert(tz_df.timezone.values[0]).reset_index()

    return df.groupby('timezone').apply(convert_tz).reset_index(drop=True)

localize_time(utc_df)

返回:

                   timestamp         timezone
0  2019-09-01 14:00:00+02:00  Europe/Brussels
1  2019-11-01 12:00:00+00:00    Europe/London

请注意时间戳列的dtype 将更改为object

utc_df.dtypes
timestamp    datetime64[ns, UTC]
timezone                  object

localize_time(utc_df).dtypes
timestamp    object
timezone     object

但是,您仍然可以访问此列的日期时间功能,只要您继续按时区分组,然后应用您想要的功能(如此处所示的示例)。

【讨论】:

以上是关于如何将具有不同时区的 tz_convert 应用于熊猫数据框中的不同行的主要内容,如果未能解决你的问题,请参考以下文章

如何将带时区的日期时间插入 SQLite?

python中datetime怎么设置时区

如何将具有不同参数的多个sklearn算法应用于多个数据帧?

在 Web 应用程序中有效地处理不同的时区

如何将 Git 补丁应用于具有不同名称和路径的文件?

具有相同时区但不同 utcoffset() 的日期时间对象