按动物ID拆分CSV单UID列至多列的Python脚本问题
修正Python脚本实现按Animal_ID聚合UID并拆分到多列
原脚本的核心问题是误解了输入数据格式——输入中每个UID单独占一行,而非同一行用逗号分隔多个UID,同时缺少按Animal_ID分组聚合UID的逻辑,导致输出完全不符合预期。以下是修正后的完整脚本:
import csv from collections import defaultdict def split_uid_by_animal(input_file, output_file): # 按Animal_ID分组,收集对应Day和所有UID animal_data = defaultdict(lambda: {'day': '', 'uids': []}) with open(input_file, 'r') as csv_file: reader = csv.DictReader(csv_file) for row in reader: animal_id = row['Animal_ID'] # 记录Day(同一Animal_ID的Day取首次值,确保一致性) if not animal_data[animal_id]['day']: animal_data[animal_id]['day'] = row['Day'] animal_data[animal_id]['uids'].append(row['UID']) # 自动计算最大UID数量,生成动态表头 max_uids_count = max(len(data['uids']) for data in animal_data.values()) new_headers = ['Day', 'Animal_ID'] + [f'UID_{i+1}' for i in range(max_uids_count)] # 构造输出行数据 new_rows = [new_headers] for animal_id, data in animal_data.items(): current_row = [data['day'], animal_id] # 填充UID,数量不足时补空字符串 current_row.extend(data['uids'] + [''] * (max_uids_count - len(data['uids']))) new_rows.append(current_row) # 写入输出文件 with open(output_file, 'w', newline='') as csv_file: writer = csv.writer(csv_file) writer.writerows(new_rows) # 调用示例 input_file = input("输入文件名: ") output_file = input("输出文件名: ") split_uid_by_animal(input_file, output_file) print("处理完成,已生成目标输出文件。")
关键修复点说明
- 分组逻辑:使用
collections.defaultdict自动按Animal_ID聚合所有关联的UID,无需手动指定每个动物的UID数量 - 动态表头:自动检测所有动物中最多的UID数量,生成对应数量的UID列(如某动物有3个UID则生成UID_1、UID_2、UID_3)
- 健壮性:通过列名读取数据(
csv.DictReader),避免原脚本依赖列索引的脆弱性 - 补空处理:自动为UID数量不足的行填充空字符串,保证输出CSV的列数一致
测试验证
输入示例:
Day,UID,Animal_ID
1,1000,H0001
1,1001,H0001
1,1002,H0002
1,1003,H0002
1,1004,H0003
1,1005,H0003
输出结果:
Day,Animal_ID,UID_1,UID_2
1,H0001,1000,1001
1,H0002,1002,1003
1,H0003,1004,1005
内容的提问来源于stack exchange,提问作者Jimmy Genome
相关产品推荐
相关产品推荐

