Python实现字典列拆分并保留关联列(UniProtKB数据处理)
问题描述
我从UniProtKB解析得到一组蛋白数据,以DataFrame形式存储,包含primaryAccession(蛋白编号)和uniProtKBCrossReferences列,其中uniProtKBCrossReferences列存储由多个字典组成的集合。
原始数据格式
| primaryAccession | uniProtKBCrossReferences |
|---|---|
| Q14457 | {'database': 'Reactome', 'id': 'R-HSA-1632852', 'properties': [{'key': 'PathwayName', 'value': 'Macroautophagy'}]}, {'database': 'Reactome', 'id': 'R-HSA-5689880', 'properties': [{'key': 'PathwayName', 'value': 'Ub-specific processing proteases'}]} |
| Q08380 | {'database': 'ProteomicsDB', 'id': '59999', 'properties': [{'key': 'Description', 'value': '-'}]}, {'database': 'Antibodypedia', 'id': '4116', 'properties': [{'key': 'antibodies', 'value': '1663 antibodies from 47 providers'}]} |
期望转换结果
| primaryAccession | database | id | properties |
|---|---|---|---|
| Q14457 | Reactome | R-HSA-1632852 | [{'key': 'PathwayName', 'value': 'Macroautophagy'}] |
| Q14457 | Reactome | R-HSA-5689880 | [{'key': 'PathwayName', 'value': 'Ub-specific processing proteases'}] |
| Q08380 | ProteomicsDB | 59999 | [{'key': 'Description', 'value': '-'}] |
| Q08380 | Antibodypedia | 4116 | [{'key': 'antibodies', 'value': '1663 antibodies from 47 providers'}] |
我使用如下dict_list_to_df函数拆分uniProtKBCrossReferences列,但该函数会丢失primaryAccession列,无法对应蛋白编号。请问如何在拆分该字典列的同时,保留primaryAccession列?
def dict_list_to_df(df, col): """Return a Pandas dataframe based on a column that contains a list of JSON objects or dictionaries. Args: df (Pandas dataframe): The dataframe to be flattened. col (str): The name of the column that contains the JSON objects or dictionaries. Returns: Pandas dataframe: A new dataframe with the JSON objects or dictionaries expanded into columns. """ rows = [] for index, row in df[col].items(): for item in row: rows.append(item) df = pd.DataFrame(rows) return df
解决方案
方法一:修改自定义函数
在遍历每一行时,将当前行的primaryAccession值添加到每个字典中,确保展开后能保留对应关系:
import pandas as pd def dict_list_to_df(df, col, id_col): """拆分包含字典集合的列,同时保留指定的关联列""" rows = [] for _, row in df.iterrows(): # 获取当前蛋白编号 primary_id = row[id_col] # 遍历字典集合中的每个条目 for item in row[col]: # 复制字典并添加蛋白编号 item_with_id = item.copy() item_with_id[id_col] = primary_id rows.append(item_with_id) # 按指定顺序整理列 return pd.DataFrame(rows)[[id_col, 'database', 'id', 'properties']]
使用示例
假设你的原始DataFrame名为protein_df,调用方式如下:
result_df = dict_list_to_df(protein_df, 'uniProtKBCrossReferences', 'primaryAccession') print(result_df)
方法二:使用Pandas原生函数(推荐)
利用explode拆分字典集合为单独行,再通过json_normalize展开字典列,最后关联primaryAccession列,代码更简洁高效:
import pandas as pd # 若原列是集合类型,先转换为列表(explode支持列表/Series类型) protein_df['uniProtKBCrossReferences'] = protein_df['uniProtKBCrossReferences'].apply(list) # 拆分每个字典为单独行 exploded_df = protein_df.explode('uniProtKBCrossReferences', ignore_index=True) # 展开字典列为独立列,并关联蛋白编号 result_df = pd.json_normalize(exploded_df['uniProtKBCrossReferences']).assign( primaryAccession=exploded_df['primaryAccession'] )[['primaryAccession', 'database', 'id', 'properties']]
内容的提问来源于stack exchange,提问作者Ana Maono
相关产品推荐
相关产品推荐

