【问题标题】:Convert CSV to restructured JSON in Python在 Python 中将 CSV 转换为重组后的 JSON
【发布时间】:2016-06-05 08:57:58
【问题描述】:

我有一个包含以下内容的 CSV 文件:

来源:data.opennepal.net

District,Zone,Geographical Region,Development Region,Causalities,In Number
Sindhupalchok,Bagmati,Mountain,Central,Total No. of Houses,66688
Sindhupalchok,Bagmati,Mountain,Central,Total Population,287798
Sindhupalchok,Bagmati,Mountain,Central,Dead Male,1497
Sindhupalchok,Bagmati,Mountain,Central,Dead Female,1943
Kathmandu,Bagmati,Hill,Central,Total No. of Houses,436344
Kathmandu,Bagmati,Hill,Central,Total Population,1744240
Kathmandu,Bagmati,Hill,Central,Dead Male,621
Kathmandu,Bagmati,Hill,Central,Dead Female,600

我的目标是从中生成一个这样的 JSON 对象:

{
  "district":{
    "Sindhupalchok":{
      "Causalities":{
        "Total No. of Houses":66688,
        "Total Population":287798,
        "Dead Male":1497,
        "Dead Female":1943
      },
      "geoInfo":{
        "Zone":"Bagmati",
        "geography":"Mountain",
        "Dev Region":"Central"
      }
    },
    "Kathmandu":{
      "Causalities":{
        "Total No. of Houses":436344,
        "Total Population":1744240,
        "Dead Male":621,
        "Dead Female":600
      },
      "geoInfo":{
        "Zone":"Bagmati",
        "geography":"Hill",
        "Dev Region":"Central"
      }
    }
  }
}

我尝试使用 csv.DictReader(csvfile, fieldnames),但它会在 JSON 中生成冗余节点,难以解析且不必要地冗长。

我正在使用 python 2.x 这是我迄今为止的尝试:

>>> csvData = open('data.csv','rb')
>>> fieldnames = ("district", "zone", "geographicalRegion", "developmentRegion", "causalities", "injuredNumber")
>>> reader = csv.DictReader(csvData, fieldnames)
>>> rawJson = json.dumps([ row for row in reader ])

rawJson 不是我一直在寻找的那个。它只是将字段名映射到各个数据集。

所以问题是:如何在没有冗余节点的情况下创建这个 JSON 对象?

【问题讨论】:

  • 你能展示你试过的代码吗?
  • @glibdud 我已经添加了我尝试过的代码。
  • 由于 CSV 和 JSON 数据不存在任何类型的 1:1 关系,您将需要遍历 CSV 数据并更手动地构建结构。只需将其构建为 dict,然后最后将其转储为 JSON。

标签: python json python-2.7 csv


【解决方案1】:

正如 glibdud 在 cmets 中提到的,您需要更手动地循环数据,以便创建所需的 JSON 结构。

我们将CSV数据的每一行读取为dict,并检查我们是否遇到了新的区,如果是,我们为它创建一个新的datadict,并插入一个geoInfo dict 变成 data。然后我们可以从该线路和该地区的后续线路收集伤亡数据。一旦我们收集了所有数据,我们就可以将 data dict 插入主 all_data dict

为了测试代码,我将您的 .csv 数据放入名为“qdata.csv”的文件中

import csv
import json

filename = 'qdata.csv'
fieldnames = ('district', 'Zone', 'geography', 
    'Dev Region', 'casualties', 'injured')

geo_keys = ('Zone', 'geography', 'Dev Region')

all_data = {}
with open(filename, 'rb') as csvfile:
    reader = csv.DictReader(csvfile, fieldnames)
    # skip header
    next(reader)
    current_district = None
    for row in reader:
        district = row['district']
        if district != current_district:
            current_district = district
            data = all_data[district] = {}
            casualties = data['Casualties'] = {}
            data['geoInfo'] = dict((k, row[k]) for k in geo_keys)
        casualties[row['casualties']] = row['injured']

print json.dumps(all_data, indent=4, sort_keys=True)    

输出

{
    "Kathmandu": {
        "Casualties": {
            "Dead Female": "600", 
            "Dead Male": "621", 
            "Total No. of Houses": "436344", 
            "Total Population": "1744240"
        }, 
        "geoInfo": {
            "Dev Region": "Central", 
            "Zone": "Bagmati", 
            "geography": "Hill"
        }
    }, 
    "Sindhupalchok": {
        "Casualties": {
            "Dead Female": "1943", 
            "Dead Male": "1497", 
            "Total No. of Houses": "66688", 
            "Total Population": "287798"
        }, 
        "geoInfo": {
            "Dev Region": "Central", 
            "Zone": "Bagmati", 
            "geography": "Mountain"
        }
    }
}

这个输出不是完全你在你的问题中得到的,但我认为你应该能够从这里得到它。 :)

【讨论】:

  • 这与问题中的不完全一样。但是,我发现你的 JSON 比我问的更棒。太感谢了。我可以从这里拿走它。如果我卡住了,StackOverflow 就在这里 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 2020-12-19
  • 2015-01-13
  • 2016-11-05
  • 2018-07-17
  • 2019-05-28
相关资源
最近更新 更多