创建pandas Series时出现'set' type is unordered报错解决方案
问题场景
- 存在名为
clinical info的pandas DataFrame,截取部分数据调用to_dict()可得到对应字典结构,需求是构建phenotype_label数据框,导出符合规范的CLS表型标签文件 - CLS文件固定为三行结构:
- 第一行:空格分隔填写样本总数、类别数、固定数值1
- 第二行:以
#开头,空格分隔列出所有类别的展示名称 - 第三行:按样本排列顺序,空格分隔列出每个样本对应的类别标签
- 代码执行到
pd.Series(val_1)时抛出TypeError: 'set' type is unordered报错,查看报错栈确认:pandas构造Series对象时不支持传入无序的set类型数据,需要修正逻辑输出符合格式要求的CLS文件。
报错根因
提取类别、样本标签的过程中,将结果保存为了set类型。set本身是无序结构,不支持索引对齐、顺序读取,pandas构造Series要求传入顺序固定的可迭代对象(如list、tuple、numpy数组),无法直接接收set作为入参。
可直接运行的实现代码
import pandas as pd # --- 按实际情况替换下面的列名、DataFrame名即可 --- # 表型列名,替换成你clinical_info里存分组标签的实际列名 pheno_col = "group" # 按DataFrame原有样本顺序提取标签,存为有序列表 sample_labels = clinical_info[pheno_col].tolist() # 提取有序类别列表:按标签首次出现的顺序去重,不要直接用set去重(会打乱顺序) category_list = list(dict.fromkeys(sample_labels)) # 如果需要自定义类别顺序/展示名,直接手动赋值即可,示例: # category_list = ["健康对照", "疾病组"] # 组装CLS三行内容 cls_line1 = f"{len(sample_labels)} {len(category_list)} 1" cls_line2 = f"# {' '.join(category_list)}" cls_line3 = " ".join(sample_labels) # 导出为CLS文件 with open("phenotype_label.cls", "w", encoding="utf-8") as f: f.write("\n".join([cls_line1, cls_line2, cls_line3]))
注意事项
- 涉及样本顺序、类别顺序的存储逻辑,禁止使用set类型。set仅适合做成员存在判断、无顺序要求的去重计算,只要涉及顺序匹配的场景,必须使用顺序固定的list、tuple等类型
- 如果对类别展示顺序有固定要求,不要依赖自动去重的结果,手动传入排序完成的类别列表即可,避免出现类别顺序和标签映射错位的问题
- 导出前可打印三行内容做校验:确认第一行的样本总数和第三行的标签个数一致,第一行的类别数和第二行的类别个数一致。
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

