python - 在 python 中处理时间序列数据:对一个时间段的序列求和和聚合
问题描述
我试图弄清楚如何可视化一些传感器数据。我每 5 分钟为多个设备收集一次数据,存储在一个看起来像这样的 JSON 结构中(请注意,我无法控制数据结构):
[
{
"group": { "id": "01234" },
"measures": {
"measures": {
"...device 1 uuid...": {
"metric.name.here": {
"mean": [
["2019-04-17T14:30:00+00:00", 300, 1],
["2019-04-17T14:35:00+00:00", 300, 2],
...
]
}
},
"...device 2 uuid...": {
"metric.name.here": {
"mean": [
["2019-04-17T14:30:00+00:00", 300, 0],
["2019-04-17T14:35:00+00:00", 300, 1],
...
]
}
}
}
}
}
]
表单的每个元组["2019-04-17T14:30:00+00:00", 300, 0]
都是[timestamp, granularity, value]
. 设备按项目 ID 分组。在任何给定的组中,我想获取多个设备的数据并将它们汇总在一起。例如,对于上述示例数据,我希望最终系列看起来像:
["2019-04-17T14:30:00+00:00", 300, 1],
["2019-04-17T14:35:00+00:00", 300, 3],
该系列的长度不一定相同。
最后,我想将这些测量结果汇总为每小时样本。
我可以得到这样的个人系列:
with open('data.json') as fd:
data = pd.read_json(fd)
for i, group in enumerate(data.group):
project = group['project_id']
instances = data.measures[i]['measures']
series_for_group = []
for instance in instances.keys():
measures = instances[instance][metric][aggregate]
# build an index from the timestamps
index = pd.DatetimeIndex(measure[0] for measure in measures)
# extract values from the data and link it to the index
series = pd.Series((measure[2] for measure in measures),
index=index)
series_for_group.append(series)
在外for
循环的底部,我有一个pandas.core.series.Series
对象数组,代表与当前组相关的不同测量集。我希望我可以像 in 一样简单地将它们添加在一起,total = sum(series_for_group)
但这会产生无效数据。
我是否正确地阅读了这些数据?这是我第一次与 Pandas 合作;我不确定(a)创建一个索引,然后(b)填充数据是否是正确的过程。
我将如何成功地将这些系列总结在一起?
我如何将这些数据重新采样为 1 小时间隔?看看这个问题,看起来
.groupby
和.agg
方法似乎很有趣,但是从那个例子中并不清楚如何指定间隔大小。
更新 1
也许我可以使用concat
and groupby
?例如:
final = pd.concat(all_series).groupby(level=0).sum()
解决方案
我在评论中建议做这样的事情:
result = pd.DataFrame({}, columns=['timestamp', 'granularity', 'value',
'project', 'uuid', 'metric', 'agg'])
for i, group in enumerate(data.group):
project = group['id']
instances = data.measures[i]['measures']
series_for_group = []
for device, measures in instances.items():
for metric, aggs in measures.items():
for agg, lst in aggs.items():
sub_df = pd.DataFrame(lst, columns = ['timestamp', 'granularity', 'value'])
sub_df['project'] = project
sub_df['uuid'] = device
sub_df['metric'] = metric
sub_df['agg'] = agg
result = pd.concat((result,sub_df), sort=True)
# parse date:
result['timestamp'] = pd.to_datetime(result['timestamp'])
这导致数据看起来像这样
agg granularity metric project timestamp uuid value
0 mean 300 metric.name.here 01234 2019-04-17 14:30:00 ...device 1 uuid... 1
1 mean 300 metric.name.here 01234 2019-04-17 14:35:00 ...device 1 uuid... 2
0 mean 300 metric.name.here 01234 2019-04-17 14:30:00 ...device 2 uuid... 0
1 mean 300 metric.name.here 01234 2019-04-17 14:35:00 ...device 2 uuid... 1
然后你可以做整体聚合
result.resample('H', on='timestamp').sum()
这使:
timestamp
2019-04-17 14:00:00 4
Freq: H, Name: value, dtype: int64
或 groupby 聚合:
result.groupby('uuid').resample('H', on='timestamp').value.sum()
这使:
uuid timestamp
...device 1 uuid... 2019-04-17 14:00:00 3
...device 2 uuid... 2019-04-17 14:00:00 1
Name: value, dtype: int64
推荐阅读
- saml-2.0 - 注销抛出证书无效签名
- javascript - VS Code 代码格式化 JavaScript 不正确
- javascript - 尝试使用枚举属性从 History 对象中提取状态时遇到 Typescript 错误
- azure - 如何将 AddAzureWebAppDiagnostics 与 IFunctionsHostBuilder 一起使用
- php - TCPDF:如何计算并在一页上放置适当的块,然后从表格开始
- selenium - Webdriver 页面源未更改
- javascript - 为什么这段代码同时使用 useMemo 和 createSelector?
- python - 使用命名参数从 Node.js (child_process) 运行 python 脚本
- wpf - 如何使用 VB.NET 区分 SHDocVw.InternetExplorer 和 SHDocVw.WebBrowser_v1?
- apache-nifi - Minifi NIFI S2S