【问题标题】:Nested dictionary to CSV convertion optimization嵌套字典到 CSV 转换优化
【发布时间】:2022-03-23 15:46:53
【问题描述】:

我有一本这样的字典:

no_empty_keys = {'783': [['4gsx', 'ADTQGS', 0.3333333333333333, {'A': ['A224', 'T226'], 'B': ['A224', 'T226']}, 504, 509], ['4gt0', 'ADTQGS', 0.3333333333333333, {'A': ['A224', 'T226'], 'B': ['A224', 'T226']}, 504, 509]],'1062': [['4gsx', 'AELTGY', 0.5, {'A': ['L175', 'T176', 'Y178'], 'B': ['L175', 'T176', 'Y178']}, 453, 458], ['4gt0', 'AELTGY', 0.5, {'A': ['L175', 'T176', 'Y178'], 'B': ['L175', 'T176', 'Y178']}, 453, 458]]}

我将其转换为 CSV 的功能是:

epitope_df = pd.DataFrame(columns=['Epitope ID', 'PDB', 'Percent Identity', 'Epitope Mapped', 'Epitope Sequence', 'Starting Position', 'Ending Position'])
                for x in no_empty_keys:
                    for y in no_empty_keys[x]:
                        epitope_df = epitope_df.append({'Epitope ID': x, 'PDB': y[0], 'Percent Identity': y[2], 'Epitope Mapped' : y[3], 'Epitope Sequence' : y[1], 'Starting Position' : y[4], 'Ending Position' : y[5]}, ignore_index=True)
                epitope_df.to_csv('test.csv', index=False)

我的输出是这样的 csv 文件:

它可以工作,但没有得到很好的优化。当我遇到超过 10,000 个条目的字典时,这个过程非常缓慢。关于如何加快这个过程的任何想法?感谢您的宝贵时间。

【问题讨论】:

    标签: python dataframe csv dictionary optimization


    【解决方案1】:

    我首先要摆脱pandas.append。将行附加到 DataFrame 是 inefficient。您可以一次性创建一个 DataFrame:

    result = []
    for x in no_empty_keys:
        for y in no_empty_keys[x]:
            result.append(
                {
                    'Epitope ID': x,
                    'PDB': y[0],
                    'Percent Identity': y[2],
                    'Epitope Mapped': y[3],
                    'Epitope Sequence': y[1],
                    'Starting Position': y[4],
                    'Ending Position': y[5]
                }
            )
    
    epitope_df = epitope_df.from_records(result)
    epitope_df.to_csv('new.csv', index=False)
    

    【讨论】:

    • 谢谢。您需要先创建变量 epitope_df。但它确实更快。快了近 10 倍(我使用 line profiler 进行了检查)。我尝试了一个不同的解决方案,使用 pd.concat,但你的仍然更快(它几乎是平局)。我将使用更扩展的字典对其进行测试。
    【解决方案2】:

    您可以手动编写临时代码或使用convtools 库,它会为您生成此类转换器:

    from convtools import conversion as c
    from convtools.contrib.tables import Table
    
    no_empty_keys = {
        "783": [
            [ "4gsx", "ADTQGS", 0.3333333333333333, {"A": ["A224", "T226"], "B": ["A224", "T226"]}, 504, 509, ],
            [ "4gt0", "ADTQGS", 0.3333333333333333, {"A": ["A224", "T226"], "B": ["A224", "T226"]}, 504, 509, ],
        ],
        "1062": [
            [ "4gsx", "AELTGY", 0.5, {"A": ["L175", "T176", "Y178"], "B": ["L175", "T176", "Y178"]}, 453, 458,],
            [ "4gt0", "AELTGY", 0.5, {"A": ["L175", "T176", "Y178"], "B": ["L175", "T176", "Y178"]}, 453, 458, ],
        ],
    }
    
    columns = (
        "Epitope ID",
        "PDB",
        "Percent Identity",
        "Epitope Mapped",
        "Epitope Sequence",
        "Starting Position",
        "Ending Position",
    )
    
    # this is just a function, so it can be run on startup once and stored for
    # further reuse
    converter = (
        c.iter(
            c.zip(
                c.repeat(c.item(0)),
                c.item(1)
            ).iter(
                (c.item(0),) + tuple(c.item(1, i) for i in range(len(columns) - 1))
            )
        )
        .flatten()
        .gen_converter()
    )
    
    # here is the stuff to profile
    Table.from_rows(
        converter(no_empty_keys.items()),
        header=columns,
    ).into_csv("out.csv")
    

    如果您对 convtools 生成的代码感到好奇,请考虑安装 black 并将 debug=True 传递给 gen_converter

    【讨论】:

      猜你喜欢
      • 2014-09-16
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      • 2022-11-25
      • 2020-10-28
      • 2021-07-23
      • 1970-01-01
      相关资源
      最近更新 更多