Python中使用defaultdict处理传感器时间序列数据问题
问题描述
我有一组格式特殊的输入数据:
data = { 'sensor1': {'units': 'x', 'values': [ {'time': '17:00', 'value': 10}, {'time': '17:10', 'value': 12}, {'time': '17:20', 'value':7}, ... ]}, 'sensor2': {'units': 'x', 'values': [ {'time': '17:00', 'value': 9}, {'time': '17:20', 'value': 11}, ... ]} }
期望输出格式如下:
{'17:00': [10,9], '17:10': [12, ''], '17:20': [7,11], ... }
核心要求:
- 输出的键是唯一且有序的时间戳
- 值为各传感器对应时间的数值列表,顺序与原字典中传感器的顺序一致
- 若某传感器在该时间点无数据,对应位置留空元素
''
我尝试用defaultdict实现,但遇到KeyError,我的代码如下:
from collections import defaultdict d = defaultdict(default_factory=list) values_list = data.values() for item in values_list: for k, v in item['values']: d[k].append(v) result = sorted(d.items())
错误原因是values_list中的每个元素是字典,无法直接用for k, v in ...遍历。
解决方法
错误点修正
你之前的代码有两处明显问题:
defaultdict的初始化错误,正确写法是defaultdict(list),而非defaultdict(default_factory=list)- 遍历
item['values']时,每个元素是字典,需通过键名获取time和value,不能直接解构为元组
方案一:分步构建结果
from collections import defaultdict # 1. 保留原字典中传感器的顺序(Python 3.7+字典默认按插入顺序存储) sensor_order = list(data.keys()) # 2. 为每个传感器构建时间-数值的映射字典,方便快速查找 sensor_time_map = {} for sensor in sensor_order: sensor_time_map[sensor] = {entry['time']: entry['value'] for entry in data[sensor]['values']} # 3. 收集所有唯一时间戳并排序 all_timestamps = sorted({ts for sensor_map in sensor_time_map.values() for ts in sensor_map.keys()}) # 4. 构建最终结果 result = defaultdict(list) for ts in all_timestamps: for sensor in sensor_order: # 存在数据则取数值,否则留空 result[ts].append(sensor_time_map[sensor].get(ts, '')) # 转换为有序普通字典(Python 3.7+直接转dict即可保持顺序) final_result = dict(sorted(result.items())) print(final_result)
方案二:高效填充式构建
这个方法直接初始化每个时间点的列表为对应传感器数量的空值,再逐个填充存在的数据,效率更高:
from collections import defaultdict sensor_order = list(data.keys()) sensor_count = len(sensor_order) # 构建传感器索引映射,快速定位列表位置 sensor_index = {sensor: idx for idx, sensor in enumerate(sensor_order)} # 初始化每个时间点的列表为全空值 time_values = defaultdict(lambda: [''] * sensor_count) for sensor in sensor_order: idx = sensor_index[sensor] for entry in data[sensor]['values']: ts = entry['time'] val = entry['value'] time_values[ts][idx] = val # 排序后转字典 final_result = dict(sorted(time_values.items())) print(final_result)
内容的提问来源于stack exchange,提问作者Feynboy
相关产品推荐
相关产品推荐

