Pandas中拆分替换列字符串并生成二进制编码列的实现
问题描述
有如下每行对应的值列表,希望将这些值拆分到不同类别并生成独立列。部分值属于同一类别,需归类到对应列:
0, Body;TSS1500 1, TSS200 2, 3, 1stExon;3'UTR 4, 5, TSS200;TSS200;TSS200 6, 1stExon;3'UTR 7, TSS1500 8, 1stExon;5'UTR 9, TSS200 10, 5'UTR;1stExon 11, TSS200;TSS200;TSS200 12, TSS1500;1stExon;TSS1500;5'UTR
期望输出为:
Body TSS UTR Other 0, 1 1 0 0 1, 0 1 0 0 2, 0 0 0 0 3, 0 0 0 1 4, 0 0 0 0 5, 0 1 0 0 6, 0 0 1 1 ...
已知可以使用pd.get_dummies(df.regions.explode()).sum(level=0),但问题在于需要按子串匹配拆分并归类(例如3'UTR和5'UTR归为UTR,TSS200和TSS1500归为TSS)。字符串可能带有未知前缀/后缀,且每个类别值以;分隔,不清楚如何组合这些操作。
解决方案
1. 定义类别映射规则
通过子串匹配确定每个片段的目标类别:
- 包含
Body→ 归入Body列 - 包含
TSS→ 归入TSS列 - 包含
UTR→ 归入UTR列 - 其他内容(如
1stExon)→ 归入Other列
2. 代码实现
第一步:准备数据
先将原始数据导入Pandas DataFrame:
import pandas as pd # 原始数据 raw_data = [ "Body;TSS1500", "TSS200", "", "1stExon;3'UTR", "", "TSS200;TSS200;TSS200", "1stExon;3'UTR", "TSS1500", "1stExon;5'UTR", "TSS200", "5'UTR;1stExon", "TSS200;TSS200;TSS200", "TSS1500;1stExon;TSS1500;5'UTR" ] df = pd.DataFrame({"regions": raw_data})
第二步:拆分、分类与统计
通过链式操作完成拆分、分类、统计:
# 定义分类函数 def map_to_category(segment): if pd.isna(segment) or segment.strip() == "": return None if "Body" in segment: return "Body" elif "TSS" in segment: return "TSS" elif "UTR" in segment: return "UTR" else: return "Other" # 执行处理流程 result = ( df["regions"] .str.split(";", expand=True) # 按分号拆分多值 .stack() # 将拆分后的列转为行,保留原始索引 .apply(map_to_category) # 映射到目标类别 .dropna() # 移除空值 .str.get_dummies() # 生成类别哑变量 .groupby(level=0).max() # 按原始行索引分组,同一类别出现多次只记1 ) # 补全所有原始行和指定列,缺失值填0 result = result.reindex(df.index, fill_value=0) result = result.reindex(columns=["Body", "TSS", "UTR", "Other"], fill_value=0) # 查看结果 print(result)
关键逻辑说明
str.split(";", expand=True).stack():把每个单元格内的多值拆分成独立行,同时保留原始行索引,方便后续按行聚合map_to_category:通过子串匹配实现灵活分类,兼容未知前缀/后缀的情况groupby(level=0).max():避免同一行内重复出现的类别被重复计数,只要出现过就标记为1reindex:确保结果包含所有原始行和指定的4列,缺失的行/列填充0,和期望输出格式对齐
内容的提问来源于stack exchange,提问作者MonteCristo
相关产品推荐
相关产品推荐

