如何按索引(时间戳)合并Python元组中的列值?
合并同时间戳的元组并填充非空值
需求:将以时间戳为第一个元素的元组列表合并,同一时间戳的多个元组合并为一个,用非空值填充对应列的空位。源数据约1440条,存在同一时间戳对应多条元组、部分列值为空的情况。
源数据示例
tuples = [('2022-10-15 01:16:00', '5', '', '', 'hdd1', '1234'), ('2022-10-15 01:16:00', '', '4', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '10', '', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '', '25', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '1', '', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '', '2', '', 'hdd1', '1234'), ...]
期望输出示例
[('2022-10-15 01:16:00', '5', '4', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '10', '25', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '1', '2', '', 'hdd1', '1234')]
当前尝试的代码问题
你当前的代码存在两个核心问题:
- 仅处理了同一时间戳最多两个元组的场景,若有更多元组则无法覆盖;
- 直接拼接元组会导致结果长度错误(比如原元组是6个元素,拼接后变成11个),且没有正确填充空值,反而额外添加了不必要的元素。
当前代码:
tuples = [('2022-10-15 01:16:00', '5', '', '', 'hdd1', '1234'), ('2022-10-15 01:16:00', '', '4', '', 'hdd1', '1234'),('2022-10-15 01:17:00', '10', '', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '', '25', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '1', '', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '', '2', '', 'hdd1', '1234')] result = [] key = lambda t: t[0] for letter,items in itertools.groupby(sorted(tuples,key=key),key): items = list(items) if len(items) == 1: result.append(items[0]+(0,0)) else: result.append(items[0]+items[1][1:]) print(result)
解决方案
正确的思路是对同一时间戳的所有元组,逐列筛选非空值,保留有效内容。具体实现如下:
import itertools tuples = [('2022-10-15 01:16:00', '5', '', '', 'hdd1', '1234'), ('2022-10-15 01:16:00', '', '4', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '10', '', '', 'hdd1', '1234'), ('2022-10-15 01:17:00', '', '25', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '1', '', '', 'hdd1', '1234'), ('2022-10-15 01:18:00', '', '2', '', 'hdd1', '1234')] result = [] key_func = lambda t: t[0] # 先按时间戳排序,确保groupby能正确分组 sorted_tuples = sorted(tuples, key=key_func) for timestamp, group in itertools.groupby(sorted_tuples, key=key_func): # 将分组内的元组转置,得到每一列的所有值 columns = list(zip(*group)) merged_columns = [] for col in columns: # 筛选当前列的非空值,取第一个;如果全空则保留空字符串 non_empty = next((val for val in col if val != ''), '') merged_columns.append(non_empty) # 将合并后的列转为元组,加入结果列表 result.append(tuple(merged_columns)) print(result)
代码说明
- 排序分组:先用
sorted按时间戳排序,保证itertools.groupby能把同一时间戳的元组归为一组(groupby要求相同键的元素连续); - 转置列处理:用
zip(*group)将分组内的元组转置,把每一列的所有值提取出来; - 填充非空值:对每一列遍历所有值,取第一个非空值;如果整列都是空,则保留空字符串;
- 合并结果:将处理后的列重新组合成元组,加入结果列表。
这个方案能处理同一时间戳下任意数量的元组,且严格保留原元组的列数,完全匹配你的期望输出。
内容的提问来源于stack exchange,提问作者Indi59
相关产品推荐
相关产品推荐

