【问题标题】:Vectorizing a Pandas apply function for tz_convert为 tz_convert 向量化 Pandas 应用函数
【发布时间】:2020-08-03 10:23:18
【问题描述】:

我有一个数据框,其中hour 列包含UTC 日期时间数据。我有一个time_zone 列,其中包含每个观察的时区,我使用它将hour 转换为本地时间并将其保存在一个名为local_hour 的新列中。为此,我使用以下代码:

import pandas as pd

# Sample dataframe
import pandas as pd
df = pd.DataFrame({
    'hour': ['2019-01-01 05:00:00', '2019-01-01 07:00:00', '2019-01-01 08:00:00'],
    'time_zone': ['US/Eastern', 'US/Central', 'US/Mountain']
})

# Ensure hour is in datetime format and localized to UTC
df['hour'] = pd.to_datetime(df['hour']).dt.tz_localize('UTC')

# Add local_hour column with hour in local time 
df['local_hour'] = df.apply(lambda row: row['hour'].tz_convert(row['time_zone']), axis=1)

df
    hour                        time_zone   local_hour
0   2019-01-01 05:00:00+00:00   US/Eastern  2019-01-01 00:00:00-05:00
1   2019-01-01 07:00:00+00:00   US/Central  2019-01-01 01:00:00-06:00
2   2019-01-01 08:00:00+00:00   US/Mountain 2019-01-01 01:00:00-07:00

代码有效。但是使用apply 运行速度很慢,因为实际上我有一个很大的数据框。有没有办法对此进行矢量化或以其他方式加快速度?

注意:我尝试过使用 swifter 包,但在我的情况下它并没有加快速度。

【问题讨论】:

  • 你试过了吗?:df['local_hour'] = df['row'].tz_convert(df['time_zone'])
  • 添加了一些示例数据。是的,我尝试了该解决方案,但它不起作用。见:stackoverflow.com/questions/57810307/…

标签: python pandas vectorization apply


【解决方案1】:

假设没有无限数量的 time_zone,也许您可​​以为每个组执行 tz_convert,例如:

df['local_hour'] = df.groupby('time_zone')['hour'].apply(lambda x: x.dt.tz_convert(x.name))
print (df)

                       hour    time_zone                 local_hour
0 2019-01-01 05:00:00+00:00   US/Eastern  2019-01-01 00:00:00-05:00
1 2019-01-01 07:00:00+00:00   US/Central  2019-01-01 01:00:00-06:00
2 2019-01-01 08:00:00+00:00  US/Mountain  2019-01-01 01:00:00-07:00

在样本上它可能会比你做的慢,但在更大的数据和组上,应该更快

对于速度比较,与您提供的 3 行的 df 相比,它给出:

%timeit df.apply(lambda row: row['hour'].tz_convert(row['time_zone']), axis=1)
# 1.6 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit df.groupby('time_zone')['hour'].apply(lambda x: x.dt.tz_convert(x.name))
# 2.58 ms ± 126 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

所以apply 更快,但是如果您创建一个大 1000 倍但只有 3 个 time_zones 的数据框,那么您的 groupby 大约快 20 倍:

df = pd.concat([df]*1000, ignore_index=True)

%timeit df.apply(lambda row: row['hour'].tz_convert(row['time_zone']), axis=1)
# 585 ms ± 42.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit df.groupby('time_zone')['hour'].apply(lambda x: x.dt.tz_convert(x.name))
# 27.5 ms ± 2.15 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

【讨论】:

  • 将 2.5M 行 df 的操作从 260 秒加快到 23 秒!
猜你喜欢
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 2014-06-11
  • 2013-11-30
  • 1970-01-01
  • 2019-08-31
  • 1970-01-01
  • 2018-09-19
相关资源
最近更新 更多