Python实现DataFrame行拆分与多值列独热编码的方法求助
问题描述
现有一份TSV格式数据,DataFrame中部分列包含分号分隔的多值,需要完成两个操作:
- 将单行按指定列的分隔值拆分为多行,每个值对应一行;
- 对部分含多值的列进行独热编码,将每个分隔值作为新列,对应行标记为1。
输入示例(TSV行):
#chr pos(1-based) ref alt aaref aaalt rs_dbSNP hg19_chr hg19_pos(1-based) hg18_chr hg18_pos(1-based) aapos genename 21 6445558 T G X C . 21 44473990 21 43347059 552;552;552;552;566 CBSA;CBSC;CBSL;CBSO;CBSL;CSBA;CSBA;CSBA
期望输出示例(TSV行):
#chr pos(1-based) ref alt aaref aaalt rs_dbSNP hg19_chr hg19_pos(1-based) hg18_chr hg18_pos(1-based) aapos CBSA CBSC CBSL CBSO CBSL CSBA CSBA CSBA 21 6445558 T G X C . 21 44473990 21 43347059 552 1 1 1 1 1 1 1 1 21 6445558 T G X C . 21 44473990 21 43347059 552 1 1 1 1 1 1 1 1 21 6445558 T G X C . 21 44473990 21 43347059 552 1 1 1 1 1 1 1 1 21 6445558 T G X C . 21 44473990 21 43347059 552 1 1 1 1 1 1 1 1 21 6445558 T G X C . 21 44473990 21 43347059 566 1 1 1 1 1 1 1 1
实现方案
使用Python的pandas库完成操作,步骤如下:
1. 导入库并读取TSV数据
import pandas as pd # 读取TSV文件,分隔符为制表符 df = pd.read_csv('input_data.tsv', sep='\t')
2. 预处理:拆分多值列为列表
将需要拆分的列(如aapos)和需要独热编码的列(如genename)按分号分割为列表,保留原数据的多值信息:
# 拆分aapos列为列表,用于后续拆分行 df['aapos'] = df['aapos'].str.split(';') # 保存genename的多值列表,用于后续独热编码 df['gene_list'] = df['genename'].str.split(';')
3. 拆分单行成多行
使用explode方法将aapos列的列表拆分为多行,每行对应一个值:
# 按aapos列拆分行,ignore_index=True重置索引 df_exploded = df.explode('aapos', ignore_index=True)
4. 生成独热编码列
遍历拆分后的每行,根据保存的gene_list生成独热编码列,每个值对应一列,值为1:
one_hot_dfs = [] for _, row in df_exploded.iterrows(): # 为当前行的gene_list生成全1的Series one_hot_series = pd.Series([1]*len(row['gene_list']), index=row['gene_list']) one_hot_dfs.append(one_hot_series) # 合并所有独热Series为DataFrame one_hot_df = pd.concat(one_hot_dfs, axis=1).T.reset_index(drop=True)
5. 合并数据并输出
将原拆分后的数据与独热编码列合并,去掉临时列后输出为TSV:
# 合并数据,移除临时的gene_list和原genename列 final_df = pd.concat([df_exploded.drop(columns=['genename', 'gene_list']), one_hot_df], axis=1) # 输出到TSV文件,不保留索引 final_df.to_csv('output_data.tsv', sep='\t', index=False)
注意事项
- 如果有多列需要独热编码,可重复步骤4的逻辑,或统一处理所有目标列;
- 若不同行的多值数量不一致,
explode会自动按目标列的列表长度拆分行,独热编码会保留所有出现过的列名,缺失值默认填0(若需要可手动调整为1或其他值)。
内容的提问来源于stack exchange,提问作者andrea99r
相关产品推荐
相关产品推荐

