【问题标题】:How to convert a file with multiple dictionaries into csv file如何将包含多个字典的文件转换为 csv 文件
【发布时间】:2019-10-16 08:51:38
【问题描述】:

我有一个包含多个字典的文件。以下只是文件的一部分。我需要将其转换为 csv 文件并最终将其加载到数据库中。我在将其转换为 csv 时遇到问题。

{"transaction_type": "new", "policynum": 4994949}
{"transaction_type": "renewal", "policynum": 3848848}
{"transaction_type": "cancel", "policynum": 49494949,  "cancel_table": 
[{"cancel_cd": "AU", "cancel_type": "online"}, {"cancel_cd": "AA", "cancel_type": "online"}]}

我已尝试实现以下代码,但取消表键未正确解析到 csv 文件中。

import ast

import csv

with open('***\\Python\\test', 'r') as in_f, open('***\\Python\\test.csv', 'w') as out_f:

    data = in_f.readlines()


    writer = csv.DictWriter(out_f, fieldnames=['transaction_type', 'policynum', 'cancel_table'], extrasaction='ignore')
    writer.writeheader()  # For writing header

    for row in data:
        dict_row = ast.literal_eval(row)  # because row has a dict string
        writer.writerow(dict_row)

下面是我得到的结果,取消表键未正确解析到 csv 文件中。我需要帮助将 cancel_type 和不同的 cancel_cd 作为单独的列。或者 cancel_cd 用逗号分隔符连接在一列中(只是一个想法)。抱歉,如果这是一个加载的问题。

transaction_type,policynum,cancel_table
new,4994949,
old,3848848,
cancel,49494949,"[{'cancel_type': 'online','cancel_cd': 'OL'}, 'cancel_type': 'Online','cancel_cd': 'BR'},{'cancel_type': 'online','cancel_cd': 'AU', }]"

【问题讨论】:

    标签: python-3.x


    【解决方案1】:

    假设cancel_table 中的行始终同时包含cancel_cdcancel_type,要将cancel_cdscancel_types 作为单独的列,您可以使用以下代码:

    import ast
    import csv
    
    with open('Python/test', 'r') as in_f, open('Python/test.csv', 'w') as out_f:
        data = in_f.readlines()
        writer = csv.DictWriter(
            out_f,
            fieldnames=[
                'transaction_type', 'policynum', 'cancel_cds', 'cancel_types'
            ],
            extrasaction='ignore')
        writer.writeheader()
    
        for row in data:
            dict_row = ast.literal_eval(row)
            if 'cancel_table' in dict_row:
                cancel_table = dict_row['cancel_table']
                cancel_cds, cancel_types = [], []
                for cancel_row in cancel_table:
                    cancel_cds.append(cancel_row['cancel_cd'])
                    cancel_types.append(cancel_row['cancel_type'])
                dict_row['cancel_cds'] = ','.join(cancel_cds)
                dict_row['cancel_types'] = ','.join(cancel_types)
            writer.writerow(dict_row)
    

    确保您没有使用逗号作为 csv 的列分隔符,否则这将导致 cancel_cdcancel_type 的每个值的列不同。

    【讨论】:

    • 谢谢乔纳森。是的,取消表总是有 cancel_cd 和 cancel_type。我将分隔符设置为管道(|)。您是否有更好的主意在 csv 文件中容纳多个 cancel_cd 而无需连接?另外,我怎样才能达到可以使用 python 处理文件的程度。我了解它的做法和经验。但是你有什么建议吗?
    • 如果您知道cancel_table 中的最大行数,您可以保留一些列来存储这些值。否则,您可以将它们存储在一个单独的文件中并将它们链接到您的主键,我假设它是policynum。为了在 Python 中处理文件,我建议阅读有关相关函数和文件解析库的文档(例如 pandas)。了解有关字符串操作和不同数据结构(如列表、字典等)的更多信息也很有用。
    • 我在输入文件“cancel_reason”中有一个新键,它的字符串值是字符串中间的 \n。这是在执行脚本时将字符串分成新行。有没有办法忽略 \n ?所以字符串值不会中断。此外,输入文件有空白/空行和需要跳过的垃圾行。我们可以编写代码将键“transaction_type”过滤为某些类型,这样我就可以逃脱空行和垃圾行吗?或者如果有其他方法?
    • 如果“忽略”是指从字符串中删除\n,只需使用dict_row['cancel_reason'].replace('\n', '')。至于跳过空行,见"how to skip blank line while reading CSV file using python"。如果您还有其他问题,请单独发布。
    猜你喜欢
    • 2020-12-24
    • 1970-01-01
    • 2021-07-23
    • 2017-03-27
    • 2018-08-13
    • 2021-12-22
    • 2023-02-24
    • 1970-01-01
    • 2016-01-28
    相关资源
    最近更新 更多