将大型数据集中的时间戳转换为多个时区

Converting timestamps in large dataset to multiple timezones

我有一个包含约 900 万行和 4 列的大型数据集 - 其中一个是 utc 时间戳。该集合中的数据已从澳大利亚的 507 个站点记录下来,并且有一个站点 ID 列。我有另一个数据集,每个站点 ID 的时区格式为 'Australia/Brisbane'。我编写了一个函数来在主数据集中创建一个新列,该列是将 utc 时间戳转换为本地时间。但是,错误的新时间与 utc 时间戳匹配,例如 2019-01-05 12:10:00+00:00 和 2019-01-13 18:55:00+11:00(错误的时区)。我相信网站在数据中没有混淆,但我已经尝试对数据进行排序以防出现问题。下面是我的代码和每个数据集第一行的图像,非常感谢任何帮助!

import pytz
from dateutil import tz

def update_timezone(df):
    newtimes = []
    df = df.sort_values('site_id')
    sites = df['site_id'].unique().tolist()
    for site in sites:
        timezone = solarbom.loc[solarbom['site_id'] == site].iloc[0, 1]
        dfsub = df[df['site_id'] == site].copy()
        dfsub['utc_timestamp'] = dfsub['utc_timestamp'].dt.tz_convert(timezone)
        newtimes.extend(dfsub['utc_timestamp'].tolist())
    df['newtimes'] = newtimes

Main large dataset Site info dataset

IIUC,您希望按 ID 对数据进行分组,然后转换特定于每个 ID 的时间戳。您可以通过使用 groupby,然后对每个组应用转换器函数来实现此目的。例如:

import pandas as pd

# dummy data:
df = pd.DataFrame({'utc_timestamp': [pd.Timestamp("2022-01-01 00:00 Z"),
                                     pd.Timestamp("2022-01-01 01:00 Z"),
                                     pd.Timestamp("2022-01-05 00:00 Z"),
                                     pd.Timestamp("2022-01-03 00:00 Z"),
                                     pd.Timestamp("2022-01-03 01:00 Z"),
                                     pd.Timestamp("2022-01-03 02:00 Z")],
                   'site_id': [1, 1, 5, 3, 3, 3],
                   'values': [11, 11, 55, 33, 33, 33]})

# time zone info for each ID:
timezdf = pd.DataFrame({'site_id': [1, 3, 5],
                        'timezone_id_x': ["Australia/Adelaide", "Australia/Perth", "Australia/Darwin"]})

### what we want:
# for row, data in timezdf.iterrows():
#     print(f"ID: {data['site_id']}, tz: {data['timezone_id_x']}")
#     print(pd.Timestamp("2022-01-01 00:00 Z"), "to", pd.Timestamp("2022-01-01 00:00 Z").tz_convert(data['timezone_id_x']))

# ID: 1, tz: Australia/Adelaide
# 2022-01-01 00:00:00+00:00 to 2022-01-01 10:30:00+10:30
# ID: 3, tz: Australia/Perth
# 2022-01-01 00:00:00+00:00 to 2022-01-01 08:00:00+08:00
# ID: 5, tz: Australia/Darwin
# 2022-01-01 00:00:00+00:00 to 2022-01-01 09:30:00+09:30
###

def converter(group, timezdf):
    # get the time zone by looking for the current group ID in timezdf
    z = timezdf.loc[timezdf["site_id"] == group["site_id"].iloc[0], 'timezone_id_x'].iloc[0]
    group["localtime"] = group["localtime"].dt.tz_convert(z)
    return group

df["localtime"] = df["utc_timestamp"]
df = df.groupby("site_id").apply(lambda g: converter(g, timezdf))

现在 df 看起来像

df
Out[71]: 
              utc_timestamp  site_id  values                  localtime
0 2022-01-01 00:00:00+00:00        1      11  2022-01-01 10:30:00+10:30
1 2022-01-01 01:00:00+00:00        1      11  2022-01-01 11:30:00+10:30
2 2022-01-05 00:00:00+00:00        5      55  2022-01-05 09:30:00+09:30
3 2022-01-03 00:00:00+00:00        3      33  2022-01-03 08:00:00+08:00
4 2022-01-03 01:00:00+00:00        3      33  2022-01-03 09:00:00+08:00
5 2022-01-03 02:00:00+00:00        3      33  2022-01-03 10:00:00+08:00