You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现字典列拆分并保留关联列(UniProtKB数据处理)

问题描述

我从UniProtKB解析得到一组蛋白数据,以DataFrame形式存储,包含primaryAccession(蛋白编号)和uniProtKBCrossReferences列,其中uniProtKBCrossReferences列存储由多个字典组成的集合。

原始数据格式

primaryAccessionuniProtKBCrossReferences
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'}]}

期望转换结果

primaryAccessiondatabaseidproperties
Q14457ReactomeR-HSA-1632852[{'key': 'PathwayName', 'value': 'Macroautophagy'}]
Q14457ReactomeR-HSA-5689880[{'key': 'PathwayName', 'value': 'Ub-specific processing proteases'}]
Q08380ProteomicsDB59999[{'key': 'Description', 'value': '-'}]
Q08380Antibodypedia4116[{'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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:47:50