【问题标题】:Convert CSV to JSON (in specific format) using Python使用 Python 将 CSV 转换为 JSON(以特定格式)
【发布时间】:2016-02-12 01:54:00
【问题描述】:

我想使用 python 2.7 将 csv 文件转换为 json 文件。下面是我尝试过的python代码,但它没有给我预期的结果。另外,我想知道是否有比我的简化版本。任何帮助表示赞赏。

这是我的 csv 文件 (SampleCsvFile.csv):

zipcode,date,state,val1,val2,val3,val4,val5
95110,2015-05-01,CA,50,30.00,5.00,3.00,3
95110,2015-06-01,CA,67,31.00,5.00,3.00,4
95110,2015-07-01,CA,97,32.00,5.00,3.00,6

这是预期的 json 文件(ExpectedJsonFile.json):

{
        "zipcode": "95110", 
        "state": "CA", 
        "subset": [
            {
                "date": "2015-05-01",
                "val1": "50", 
                "val2": "30.00", 
                "val3": "5.00", 
                "val4": "3.00", 
                "val5": "3"
            }, 
            {
                "date": "2015-06-01", 
                "val1": "67", 
                "val2": "31.00", 
                "val3": "5.00", 
                "val4": "3.00", 
                "val5": "4"
            }, 
            {
                "date": "2015-07-01", 
                "val1": "97", 
                "val2": "32.00", 
                "val3": "5.00", 
                "val4": "3.00", 
                "val5": "6"
            }
        ]

}

这是我试过的python代码:

import pandas as pd
from itertools import groupby 
import json    

df = pd.read_csv('SampleCsvFile.csv')

names = df.columns.values.tolist()
data = df.values

master_list2 = [ (d["zipcode"], d["state"], d) for d in [dict(zip(names, d)) for d in data] ]
intermediate2 = [(k, [x[2] for x in list(v)]) for k,v in groupby(master_list2, lambda t: (t[0],t[1]) )]
nested_json2 = [dict(zip(names,(k[0][0], k[0][1], k[1]))) for k in [(i[0], i[1]) for i in intermediate2]]

#print json.dumps(nested_json2, indent=4)
with open('ExpectedJsonFile.json', 'w') as outfile:
     outfile.write(json.dumps(nested_json2, indent=4))

【问题讨论】:

    标签: python json python-2.7 csv python-3.x


    【解决方案1】:

    由于您已经在使用 pandas,我试图从数据框方法中获得尽可能多的里程。我最终也与您的实施相去甚远。不过,我认为这里的关键是不要试图对你的列表和/或字典理解变得太聪明。您很容易混淆自己和阅读您代码的每个人。

    import pandas as pd
    from itertools import groupby 
    from collections import OrderedDict
    import json    
    
    df = pd.read_csv('SampleCsvFile.csv', dtype={
                "zipcode" : str,
                "date" : str,
                "state" : str,
                "val1" : str,
                "val2" : str,
                "val3" : str,
                "val4" : str,
                "val5" : str
            })
    
    results = []
    
    for (zipcode, state), bag in df.groupby(["zipcode", "state"]):
        contents_df = bag.drop(["zipcode", "state"], axis=1)
        subset = [OrderedDict(row) for i,row in contents_df.iterrows()]
        results.append(OrderedDict([("zipcode", zipcode),
                                    ("state", state),
                                    ("subset", subset)]))
    
    print json.dumps(results[0], indent=4)
    #with open('ExpectedJsonFile.json', 'w') as outfile:
    #    outfile.write(json.dumps(results[0], indent=4))
    

    将所有 json 数据类型写入字符串并保留其原始格式的最简单方法是强制 read_csv 将它们解析为字符串。但是,如果您需要在写出 json 之前对值进行任何数值操作,则必须允许 read_csv 对它们进行数值解析并在转换为 json 之前将它们强制转换为正确的字符串格式。

    【讨论】:

    • 当我尝试执行您的代码时,我收到类型错误:95110 is not JSON serializable。此外,输出没有数值的双引号并截断小数部分。关于如何解决它的任何想法?
    • 这是“打印结果”的输出(没有 json.dumps):{'subset': [{'val3': 5.0, 'date': '2015-05-01', 'val2': 30.0, 'val1': 50L, 'val5': 3L, 'val4': 3.0}, {'val3': 5.0, 'date': '2015-06-01', 'val2': 31.0, 'val1': 67L, 'val5': 4L, 'val4': 3.0}, {'val3': 5.0, 'date': '2015-07-01', 'val2': 32.0, 'val1': 97L, 'val5': 6L, 'val4': 3.0}], 'state': 'CA', 'zipcode': 95110}
    • 我调整了答案以强制将所有数据类型读取为字符串,这将解决引用和数字格式问题。我不确定您遇到的类型错误,因为我无法复制它,但由于解析的邮政编码的数据类型不同,现在也有可能得到解决。
    • 新代码就像一个魅力。非常感谢 Aniket,我真的很感激。
    • 一个问题,有没有办法改变/设置元素的顺序?例如,我想在顶部查看状态和邮政编码,在底部查看子集。现在,顺序似乎是随机的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 2020-11-06
    • 2019-02-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多