У меня есть временная серия, состоящая из следующего списка:
for i in range(10):
d = {
'ts': i,
'ts_offset': 6 * 60 * 60,
'value': 1234.0
}
if i >= 5:
d['ts_offset'] = 12 * 60 * 60
data.append(d)
frame = pd.DataFrame(data)
frame.index = pd.to_datetime(frame.ts, unit='s')
ts ts_offset value
ts
1970-01-01 00:00:00 0 21600 1234.0
1970-01-01 00:00:01 1 21600 1234.0
1970-01-01 00:00:02 2 21600 1234.0
1970-01-01 00:00:03 3 21600 1234.0
1970-01-01 00:00:04 4 21600 1234.0
1970-01-01 00:00:05 5 43200 1234.0
1970-01-01 00:00:06 6 43200 1234.0
1970-01-01 00:00:07 7 43200 1234.0
1970-01-01 00:00:08 8 43200 1234.0
1970-01-01 00:00:09 9 43200 1234.0
Индекс - это временная метка плюс смещение, зависящее от локализации (в секундах).Как вы можете видеть, мой вариант использования заключается в том, что смещение может измениться в любой момент времени.Я хотел бы преобразовать эту конструкцию в серию, где индексом является локализованный pd.TimeSeriesIndex, но пока мне удалось найти только функции локализации, которые работали над всем индексом.
Кто-нибудь знает эффективный метод для преобразования каждого индекса с (возможно) отдельным часовым поясом?Серия может состоять из нескольких тысяч строк, и эта функция будет вызываться много, поэтому я хотел бы векторизовать ее как можно больше.
Редактировать:
Я взял на себя смелость выбрать решение для группировки FLabs по сравнению с простым циклом Python со следующим скриптом:
import pandas as pd
import numpy as np
import datetime
def to_series1(data, metric):
idx = []
values = []
for i in data:
tz = datetime.timezone(datetime.timedelta(seconds=i["ts_offset"]))
idx.append(pd.Timestamp(i["ts"] * 10**9, tzinfo=tz))
values.append(np.float(i["value"]))
series = pd.Series(values, index=idx, name=metric)
return series
def to_series2(data, metric):
frame = pd.DataFrame(data)
frame.index = pd.to_datetime(frame.ts, unit='s', utc=True)
grouped = frame.groupby('ts_offset')
out = {}
for name, group in grouped:
out[name] = group
tz = datetime.timezone(datetime.timedelta(seconds=name))
out[name].index = out[name].index.tz_convert(tz)
out = pd.concat(out, axis=0).sort_index(level='ts')
out.index = out.index.get_level_values('ts')
series = out.value
series.name = metric
series.index.name = None
return series
metric = 'bla'
data = []
for i in range(100000):
d = {
'ts': i,
'ts_offset': 6 * 60 * 60,
'value': 1234.0
}
if i >= 50000:
d['ts_offset'] = 12 * 60 * 60
data.append(d)
%timeit to_series1(data, metric)
%timeit to_series2(data, metric)
Результаты были следующие:
2.59 s ± 113 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
3.03 s ± 125 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Итак, я 'Я по-прежнему открыт для предложений, которые, возможно, быстрее.