如何根据DataFrame中值的出现情况转换并填充新DataFrame
问题描述
现有如下结构的DataFrame:
Names1 Gene_name Status SP1 GENE1 0 SP1 GENE1 1 SP1 GENE1 1 SP1 GENE1 2 SP1 GENE1 2 SP1 GENE2 0 SP3 GENE2 0 SP1 GENE2 1 SP2 GENE2 2 SP4 GENE3 1 SP4 GENE3 2 SP5 GENE3 0 SP5 GENE3 0
需要生成一个新DataFrame,以Gene_name作为列名,Names作为行索引,根据每组Names对应的Status值的出现情况填充单元格:
- 仅出现0 → 值为0
- 仅出现1 → 值为1
- 同时出现0和1 → 值为0-1
- 同时出现0和2 → 值为0-2
- 同时出现1和2 → 值为1-2
- 同时出现0、1和2 → 值为0-1-2
无对应值的单元格填充NA,最终目标DataFrame如下:
Names GENE1 GENE2 GENE3 SP1 0-1-2 0-1 NA SP2 NA 2 NA SP3 NA 0 NA SP4 NA NA 1-2 SP5 NA NA 0
附原DataFrame的字典格式:
{'Names1': {0: 'SP1', 1: 'SP1', 2: 'SP1', 3: 'SP1', 4: 'SP1', 5: 'SP1', 6: 'SP3', 7: 'SP1', 8: 'SP2', 9: 'SP4', 10: 'SP4', 11: 'SP5', 12: 'SP5'}, 'Gene_name': {0: 'GENE1', 1: 'GENE1', 2: 'GENE1', 3: 'GENE1', 4: 'GENE1', 5: 'GENE2', 6: 'GENE2', 7: 'GENE2', 8: 'GENE2', 9: 'GENE3', 10: 'GENE3', 11: 'GENE3', 12: 'GENE3'}, 'Status': {0: 0, 1: 1, 2: 1, 3: 2, 4: 2, 5: 0, 6: 0, 7: 1, 8: 2, 9: 1, 10: 2, 11: 0, 12: 0}}
解决方案
可以通过分组处理+表格重塑两步完成需求:
- 分组提取唯一状态并格式化:按
Names1和Gene_name分组,提取每组内唯一的Status值,排序后用-连接成指定格式的字符串。 - 转为宽表并调整格式:将分组结果转换为宽表,设置行索引为
Names,缺失值填充为NA。
具体代码如下:
import pandas as pd # 加载原始数据 data = {'Names1': {0: 'SP1', 1: 'SP1', 2: 'SP1', 3: 'SP1', 4: 'SP1', 5: 'SP1', 6: 'SP3', 7: 'SP1', 8: 'SP2', 9: 'SP4', 10: 'SP4', 11: 'SP5', 12: 'SP5'}, 'Gene_name': {0: 'GENE1', 1: 'GENE1', 2: 'GENE1', 3: 'GENE1', 4: 'GENE1', 5: 'GENE2', 6: 'GENE2', 7: 'GENE2', 8: 'GENE2', 9: 'GENE3', 10: 'GENE3', 11: 'GENE3', 12: 'GENE3'}, 'Status': {0: 0, 1: 1, 2: 1, 3: 2, 4: 2, 5: 0, 6: 0, 7: 1, 8: 2, 9: 1, 10: 2, 11: 0, 12: 0}} df = pd.DataFrame(data) # 定义格式化函数:提取唯一状态、排序后连接 def format_status(group): unique_status = sorted(group['Status'].unique()) return '-'.join(map(str, unique_status)) # 分组处理并转为宽表 result = df.groupby(['Names1', 'Gene_name']).apply(format_status).unstack() # 调整索引和列名,填充缺失值 result = result.rename_axis('Names').rename_axis(None, axis=1).fillna('NA') print(result)
运行后输出结果与需求一致,其中SP4的GENE3值为1-2(符合原始数据中该组仅出现1和2的事实)。
内容的提问来源于stack exchange,提问作者chippycentra
相关产品推荐
相关产品推荐

