高效合并文件并扩展元数据:基于CHR与POS的邻近匹配填充需求
内存高效的位置元数据匹配方案
核心思路
由于原始文件和处理后文件均已按CHR和POS升序排序,我们可以采用双指针迭代遍历的方式,无需将整个文件加载到内存中,仅保留当前及后续少量处理后文件的行作为候选,即可为每个原始位置找到符合规则的元数据。
对应规则的具体处理逻辑:
- 仅匹配同
CHR的行 - 当原始位置与两个处理后位置距离相等时,选择
POS更大的那一行 - 若原始位置超出处理后文件的最后一个
POS,直接复用处理后文件的最后一行元数据
实现代码(Python)
def match_metadata(original_path, processed_path, output_path): with open(original_path, 'r') as orig_f, \ open(processed_path, 'r') as proc_f, \ open(output_path, 'w') as out_f: # 读取并写入表头 orig_header = orig_f.readline().strip() proc_header = proc_f.readline().strip() out_f.write(f"{proc_header}\n") # 初始化处理后文件的迭代器和候选行 proc_lines = iter(proc_f) current_proc_line = next(proc_lines).strip().split() next_proc_line = None # 提前读取下一行作为候选(若存在) try: next_proc_line = next(proc_lines).strip().split() except StopIteration: pass for orig_line in orig_f: orig_parts = orig_line.strip().split() if not orig_parts: continue orig_chr, orig_pos = orig_parts[0], int(orig_parts[1]) # 切换到当前原始行对应的CHR(适配多染色体场景) while current_proc_line[0] != orig_chr: try: current_proc_line = next_proc_line next_proc_line = next(proc_lines).strip().split() except StopIteration: next_proc_line = None break # 滑动到不小于当前原始POS的第一个处理后行 while next_proc_line is not None and next_proc_line[0] == orig_chr and int(next_proc_line[1]) < orig_pos: current_proc_line = next_proc_line try: next_proc_line = next(proc_lines).strip().split() except StopIteration: next_proc_line = None break # 选择最接近的候选行 best_line = current_proc_line if next_proc_line is not None and next_proc_line[0] == orig_chr: current_pos = int(current_proc_line[1]) next_pos = int(next_proc_line[1]) dist_current = orig_pos - current_pos dist_next = next_pos - orig_pos # 距离相等选大POS,或下一行距离更近时切换 if dist_next <= dist_current: best_line = next_proc_line # 写入结果:原始坐标 + 匹配到的元数据 out_f.write(f"{orig_chr}\t{orig_pos}\t{'\t'.join(best_line[2:])}\n") # 处理后文件已遍历到末尾,后续所有行复用最后一行 if next_proc_line is None: current_proc_line = best_line # 调用示例(替换为你的实际文件路径) match_metadata("original.txt", "processed.txt", "output.txt")
代码说明
- 内存效率:采用迭代器逐行读取文件,仅同时保留最多3行数据在内存中,完全适配百万级行的超大文件场景。
- 规则适配:
- 双指针滑动确保只在同
CHR范围内查找匹配项 - 通过
dist_next <= dist_current的判断,同时覆盖“距离更小选对应行”和“距离相等选大POS”的规则 - 处理后文件遍历结束后,自动将最后一行元数据复用给后续所有原始行
- 双指针滑动确保只在同
- 兼容性:天然支持多染色体文件,自动切换对应染色体的处理后行数据。
示例验证
用你提供的示例数据运行代码,输出结果与预期完全一致:
CHR POS sample1 sample2 sample3 sample4 sample5 sample6 1 100 0 1 2 1 0 2 1 200 0 1 2 1 0 2 1 300 0 1 2 1 1 2 1 400 0 1 2 1 1 2 1 500 2 0 1 0 2 1 1 600 0 1 2 1 0 2 1 700 0 1 2 1 0 2 1 800 0 1 2 1 0 2 1 900 0 1 2 1 2 2 1 1000 0 1 2 1 2 2
内容的提问来源于stack exchange,提问作者binf-er
相关产品推荐
相关产品推荐

