使用Python将CSV转换为特定格式的JSON

3
我可以帮您将csv文件转换为json文件,使用的是Python 2.7版本。以下是我尝试的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))
1个回答

2

既然您已经在使用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。


我调整了答案,强制将所有数据类型读取为字符串,这将解决引用和数字格式问题。我不确定您遇到的类型错误,因为我无法复制该错误,但由于解析后的邮政编码的数据类型现在不同,因此有可能也会得到解决。 - Aniket Schneider
新代码运行得非常好。非常感谢Aniket,我真的很感激。 - Steve
更新了答案以强制排序。请注意,JSON对象被视为无序集合,因此任何解析JSON的内容都不应关心顺序。但是,为了人类可读性,您可以使用Python OrderedDict来设置所需的顺序。 - Aniket Schneider
明白了。再次感谢! - Steve
刚刚完成了。 :) 感谢您的提醒。 - Steve
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接