【问题标题】:Construct a pandas DataFrame from items in a nested dictionary with lists as inner values从嵌套字典中的项目构造一个 Pandas DataFrame,其中列表作为内部值
【发布时间】:2021-12-31 01:40:03
【问题描述】:

我有一个嵌套字典annot_dict,其结构:

  • key = 长唯一字符串
  • 值 = 字典列表

值,字典列表,每个都有结构:

  • key = 长唯一字符串(上层字典键的子类别)
  • 值 = 五个字符串项的列表

整个结构的一个例子是:

annot_dict['ID_string'] = [
     {'ID_string': ['attr1a', 'attr1b', 'attr1c', 'attr1d', 'attr1e']},
     {'string2'  : ['attr2a', 'attr2b', 'attr2c', 'attr2d', 'attr2e']},
     {'string3'  : ['attr3a', 'attr3b', 'attr3c', 'attr3d', 'attr3e']},
             ]

ID_string 与第一个子字典键相同。这是我编写的 gff3 文件解析器函数的输出,真正的字典信息是来自人类 9 号染色体基因组的基因 (ID_string) 和转录本 (string2, string3,...),如果有人的话熟悉该文件类型的结构。属性列表描述了生物型、起始索引、结束索引、链和描述。

我现在想将这些信息放入 pandas DataFrame 中。我想遍历 dict 中最外层的键(ID_strings),以创建一个大 DataFrame,其中包含每个 ID_string 的行和它下面的每个子类别的行(string2string3)。

我希望它看起来像这样:

| subunit_ID |  gene_ID  | start_index | end_index | strand |biotype | desc   |
|------------|-----------|-------------|-----------|--------|--------|--------|
|'ID_string' |'ID_string'|  'attr1a'   | 'attr1b'  |'attr1c'|'attr1d'|'attr1e'|
| 'string2'  |'ID_string'|  'attr2a'   | 'attr2b'  |'attr2c'|'attr2d'|'attr2e'|
| 'string3'  |'ID_string'|  'attr3a'   | 'attr3b'  |'attr3c'|'attr3d'|'attr3e'|

我确实看过other answers,但没有一个与我的字典结构完全相同。这是我关于 SO 的第一个问题,因此请随时提高我的问题的可理解性。

【问题讨论】:

  • 如何提供'subunit_ID'、'gene_ID'、'start_index'、'end_index'、'strand'、'biotype'、'desc'? “gene_ID”是如何填写的?你尝试了什么?

标签: python pandas dataframe dictionary


【解决方案1】:

您可以使用列表推导将 dicts 展平为包含 dict 键作为项目的列表,然后将其加载到 pandas:

import pandas as pd

annot_dict = {}
annot_dict['ID_string'] = [
     {'ID_string': ['attr1a', 'attr1b', 'attr1c', 'attr1d', 'attr1e']},
     {'string2'  : ['attr2a', 'attr2b', 'attr2c', 'attr2d', 'attr2e']},
     {'string3'  : ['attr3a', 'attr3b', 'attr3c', 'attr3d', 'attr3e']},
             ]

df = pd.DataFrame([[k]+list(annot_dict['ID_string'][0].keys())+v for i in annot_dict['ID_string'] for k, v in i.items()], columns=['subunit_ID','gene_ID','start_index','end_index','strand','biotype','desc'])

输出:

subunit_ID gene_ID start_index end_index strand biotype desc
0 ID_string ID_string attr1a attr1b attr1c attr1d attr1e
1 string2 ID_string attr2a attr2b attr2c attr2d attr2e
2 string3 ID_string attr3a attr3b attr3c attr3d attr3e

【讨论】:

    【解决方案2】:

    你可以这样做:

    df =  pd.DataFrame(
        (
            [subkey, key] + value
            for key, records in annot_dict.items()
            for record in records
            for subkey, value in record.items()
        ),
        columns=[
            'subunit_ID', 'gene_ID', 'start_index', 'end_index', 'strand','biotype', 'desc'
        ]
    )
    

    结果

    annot_dict = {
        'ID_string1': [
            {'ID_string1': ['attr11a', 'attr11b', 'attr11c', 'attr11d', 'attr11e']},
            {'string12'  : ['attr12a', 'attr12b', 'attr12c', 'attr12d', 'attr12e']},
            {'string13'  : ['attr13a', 'attr13b', 'attr13c', 'attr13d', 'attr13e']},
        ],
        'ID_string2': [
            {'ID_string2': ['attr21a', 'attr21b', 'attr21c', 'attr21d', 'attr21e']},
            {'string22'  : ['attr22a', 'attr22b', 'attr22c', 'attr22d', 'attr22e']},
            {'string23'  : ['attr23a', 'attr23b', 'attr23c', 'attr23d', 'attr23e']},
        ]
    }
    

       subunit_ID     gene_ID start_index end_index   strand  biotype     desc
    0  ID_string1  ID_string1     attr11a   attr11b  attr11c  attr11d  attr11e
    1    string12  ID_string1     attr12a   attr12b  attr12c  attr12d  attr12e
    2    string13  ID_string1     attr13a   attr13b  attr13c  attr13d  attr13e
    3  ID_string2  ID_string2     attr21a   attr21b  attr21c  attr21d  attr21e
    4    string22  ID_string2     attr22a   attr22b  attr22c  attr22d  attr22e
    5    string23  ID_string2     attr23a   attr23b  attr23c  attr23d  attr23e
    

    【讨论】:

    • 完美!谢谢@Timus
    猜你喜欢
    • 2012-11-14
    • 2023-01-21
    • 2016-07-24
    • 1970-01-01
    • 2017-12-26
    • 2021-06-13
    • 2023-04-02
    • 2015-10-25
    • 1970-01-01
    相关资源
    最近更新 更多