分别本地化熊猫时间戳索引的每一行



我有一个由dicts列表组成的时间序列,如下所示:

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)

因此,我仍然对可能更快的建议持开放态度。

您可以使用groupbyts_offset,这样您就可以对数据帧应用单个偏移量(矢量化操作(:

grouped = frame.groupby('ts_offset')
out = {}
for name, group in grouped:
print(name)
out[name] = group
out[name].index = out[name].index + pd.DateOffset(seconds=name)
out = pd.concat(out, axis=0, names=['offset', 'ts']).sort_index(level='ts')

显示应用的偏移量只是为了验证结果,您有:

Out[17]: 
ts  ts_offset   value
ts                                        
21600 1970-01-01 06:00:00   0      21600  1234.0
1970-01-01 06:00:01   1      21600  1234.0
1970-01-01 06:00:02   2      21600  1234.0
1970-01-01 06:00:03   3      21600  1234.0
1970-01-01 06:00:04   4      21600  1234.0
43200 1970-01-01 12:00:05   5      43200  1234.0
1970-01-01 12:00:06   6      43200  1234.0
1970-01-01 12:00:07   7      43200  1234.0
1970-01-01 12:00:08   8      43200  1234.0
1970-01-01 12:00:09   9      43200  1234.0

最后,您可以删除第一个索引:

out.index = out.index.get_level_values('ts')

最新更新