Python中压缩大范围为小范围并保留标签,合并预测序列元组输出
嘿,看来你已经把预测序列转换成了带时间区间的标签元组,现在想把这些零散的区间合并得更贴合实际、更像人类的简洁表述对吧?我给你整理几个实用的思路和代码示例,你可以根据自己的数据集调整:
1. 先合并连续/重叠的同标签区间
这是最基础的一步,把相邻或者有重叠的相同标签区间合并成一个完整的大区间。比如如果你的输出里有[0,2,'谢'], [3,5,'谢'],直接合并成[0,5,'谢']就更合理。
代码示例:
def merge_continuous_same_label(intervals): if not intervals: return [] # 先按起始时间排序,确保区间是按时间顺序来的 sorted_intervals = sorted(intervals, key=lambda x: x[0]) merged = [sorted_intervals[0]] for current in sorted_intervals[1:]: last = merged[-1] # 如果当前标签和上一个一致,且时间上连续/重叠(这里+1是允许相邻区间,可按需调整) if current[2] == last[2] and current[0] <= last[1] + 1: # 更新合并后的区间结束时间为两者的最大值 merged[-1] = [last[0], max(last[1], current[1]), last[2]] else: merged.append(current) return merged
2. 过滤并合并噪声小片段
预测结果里经常会出现一些极短的、不符合实际的小标签片段(比如中间插了1帧的无关标签),人类会自动忽略这种噪声。你可以设置一个最小长度阈值,把这些短片段合并到前后占比更高的标签里。
代码示例:
def merge_noisy_intervals(intervals, min_valid_length=3): # 这里的3是你认为的"有效"片段长度,可改 if not intervals: return [] sorted_intervals = sorted(intervals, key=lambda x: x[0]) merged = [] i = 0 while i < len(sorted_intervals): curr_start, curr_end, curr_label = sorted_intervals[i] curr_length = curr_end - curr_start + 1 # 如果当前片段太短,尝试合并到前后的同标签区间 if curr_length < min_valid_length: # 先看前一个区间是不是同标签 if merged and merged[-1][2] == curr_label: merged[-1] = [merged[-1][0], curr_end, merged[-1][2]] # 再看后一个区间是不是同标签 elif i + 1 < len(sorted_intervals) and sorted_intervals[i+1][2] == curr_label: next_start, next_end, next_label = sorted_intervals[i+1] merged.append([curr_start, next_end, curr_label]) i += 1 # 跳过下一个,因为已经合并了 else: # 前后都没同标签的话,要么保留要么合并到占比高的相邻区间,这里先简单保留 merged.append(sorted_intervals[i]) else: merged.append(sorted_intervals[i]) i += 1 # 合并完噪声后,再跑一遍连续同标签合并 return merge_continuous_same_label(merged)
3. 语义层面的标签合并(针对文本类标签)
如果你的标签是单字文本(比如'谢'),合并完区间后还可以做语义层面的拼接,把连续的相同单字拼成完整词语,比如把连续的'谢'区间合并成'谢谢'。
代码示例:
def merge_semantic_text_labels(merged_intervals): if not merged_intervals: return [] final_result = [] curr_start, curr_end, curr_label = merged_intervals[0] for interval in merged_intervals[1:]: start, end, label = interval # 如果是相同的单字标签,直接拼接 if label == curr_label and len(curr_label) == 1: curr_label += label curr_end = end else: final_result.append([curr_start, curr_end, curr_label]) curr_start, curr_end, curr_label = start, end, label final_result.append([curr_start, curr_end, curr_label]) return final_result
组合使用示例
你可以把这几个方法串起来用,先过滤噪声,再合并连续区间,最后做语义拼接:
# 假设你的原始输出是raw_intervals cleaned = merge_noisy_intervals(raw_intervals) continuous_merged = merge_continuous_same_label(cleaned) final_output = merge_semantic_text_labels(continuous_merged)
记得根据自己的实际数据调整阈值(比如min_valid_length、连续区间判断的+1),如果你的标签不是文本,那可以跳过语义合并的步骤~
内容的提问来源于stack exchange,提问作者DJ_Stuffy_K
相关产品推荐
相关产品推荐

