【问题标题】:How to convert CSV file to multiline JSON?如何将 CSV 文件转换为多行 JSON?
【发布时间】:2013-11-10 22:43:42
【问题描述】:

这是我的代码,非常简单的东西......

import csv
import json

csvfile = open('file.csv', 'r')
jsonfile = open('file.json', 'w')

fieldnames = ("FirstName","LastName","IDNumber","Message")
reader = csv.DictReader( csvfile, fieldnames)
out = json.dumps( [ row for row in reader ] )
jsonfile.write(out)

声明一些字段名,阅读器使用CSV读取文件,文件名将文件转储为JSON格式。问题来了……

CSV 文件中的每条记录位于不同的行上。我希望 JSON 输出以相同的方式。问题是它把它全部倾倒在一条巨大的长线上。

我尝试使用for line in csvfile: 之类的东西,然后使用reader = csv.DictReader( line, fieldnames) 在下面运行我的代码,它循环遍历每一行,但它在一行上执行整个文件,然后在另一行上循环遍历整个文件。 .. 继续,直到用完为止。

有什么纠正这个问题的建议吗?

编辑:澄清一下,目前我有:(第 1 行的每条记录)

[{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"},{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}]

我在寻找什么:(2 行 2 条记录)

{"FirstName":"John","LastName":"Doe","IDNumber":"123","Message":"None"}
{"FirstName":"George","LastName":"Washington","IDNumber":"001","Message":"Something"}

不是每个单独的字段都缩进/在单独的行上,而是每条记录都在自己的行上。

一些样本输入。

"John","Doe","001","Message1"
"George","Washington","002","Message2"

【问题讨论】:

  • 我不确定你的代码是否完全如你所说;它应该产生[{..row..},{..row..},...] 而不是{..row..}{..row..}..。也就是说,输出看起来会是一个json对象的json数组,而不是未连接的json对象流。

标签: python json csv


【解决方案1】:

indent参数添加到json.dumps

 data = {'this': ['has', 'some', 'things'],
         'in': {'it': 'with', 'some': 'more'}}
 print(json.dumps(data, indent=4))

还请注意,您可以简单地将json.dump 与打开的jsonfile 一起使用:

json.dump(data, jsonfile)

【讨论】:

  • 不是我想要的。我编辑了我的原始问题以澄清并显示所需的输出。不过感谢您的提示,这可能稍后会派上用场。
【解决方案2】:
import csv
import json
csvfile = csv.DictReader('filename.csv', 'r'))
output =[]
for each in csvfile:
    row ={}
    row['FirstName'] = each['FirstName']
    row['LastName']  = each['LastName']
    row['IDNumber']  = each ['IDNumber']
    row['Message']   = each['Message']
    output.append(row)
json.dump(output,open('filename.json','w'),indent=4,sort_keys=False)

【讨论】:

  • 当我尝试使用它时,我得到“KeyError:'FirstName'”。似乎没有添加密钥。我不确定您到底想在这里做什么,但我认为输出与我正在寻找的不匹配,因为您使用与韦恩相同的 indent=4。我应该期待什么输出?我编辑了我的原始帖子以澄清我在寻找什么。
  • 关键错误很可能是因为这段代码没有将 headers 参数传递给DictReader,所以它从输入文件的第一行猜测字段名称:John, Doe, 5, "无”而不是“名、姓”等等...
  • 更好的选择,这个选项实际上解析了所需字段的 CSV(不仅仅是按顺序,如标记的答案中那样)
  • 我收到一条错误消息:TypeError: expected string or buffer
【解决方案3】:

您想要的输出的问题是它不是有效的 json 文档;这是一个 json 文档流

没关系,如果它是您需要的,但这意味着对于您想要在输出中的每个文档,您必须调用 json.dumps

由于您要分隔文档的换行符不包含在这些文档中,因此您必须自己提供它。所以我们只需要将循环从对 json.dump 的调用中拉出来,并为每个写入的文档插入换行符。

import csv
import json

csvfile = open('file.csv', 'r')
jsonfile = open('file.json', 'w')

fieldnames = ("FirstName","LastName","IDNumber","Message")
reader = csv.DictReader( csvfile, fieldnames)
for row in reader:
    json.dump(row, jsonfile)
    jsonfile.write('\n')

【讨论】:

  • 完美!抱歉,您必须做一些读心术才能得到它,并感谢您的更正/澄清。这正是我想要的。
  • 但问题是 outfile 不是有效的 json
  • @MONTYHS:这个答案的第一句话解释了 outfile 不是 json 文档;以及它是什么。您与提出此问题的人有不同的问题吗?
  • @abhi1610:如果您希望输入中有标题,则应构造 DictReader 而不提供 fieldnames 参数;然后它将读取第一行以从文件中获取字段名。
  • 最好为你的文件添加编码csvfile = open('file.csv', 'r',encoding='utf-8')jsonfile = open('file.json', 'w',encoding='utf-8')
【解决方案4】:

作为对@MONTYHS 答案的轻微改进,遍历一组字段名:

import csv
import json

csvfilename = 'filename.csv'
jsonfilename = csvfilename.split('.')[0] + '.json'
csvfile = open(csvfilename, 'r')
jsonfile = open(jsonfilename, 'w')
reader = csv.DictReader(csvfile)

fieldnames = ('FirstName', 'LastName', 'IDNumber', 'Message')

output = []

for each in reader:
  row = {}
  for field in fieldnames:
    row[field] = each[field]
output.append(row)

json.dump(output, jsonfile, indent=2, sort_keys=True)

【讨论】:

    【解决方案5】:

    你可以试试this

    import csvmapper
    
    # how does the object look
    mapper = csvmapper.DictMapper([ 
      [ 
         { 'name' : 'FirstName'},
         { 'name' : 'LastName' },
         { 'name' : 'IDNumber', 'type':'int' },
         { 'name' : 'Messages' }
      ]
     ])
    
    # parser instance
    parser = csvmapper.CSVParser('sample.csv', mapper)
    # conversion service
    converter = csvmapper.JSONConverter(parser)
    
    print converter.doConvert(pretty=True)
    

    编辑:

    更简单的方法

    import csvmapper
    
    fields = ('FirstName', 'LastName', 'IDNumber', 'Messages')
    parser = CSVParser('sample.csv', csvmapper.FieldMapper(fields))
    
    converter = csvmapper.JSONConverter(parser)
    
    print converter.doConvert(pretty=True)
    

    【讨论】:

    • 我认为您至少应该明确提及您正在使用第三方模块 csvmapper 来执行此操作(可能从哪里获取)而不是构建的东西-in.
    【解决方案6】:

    我将@SingleNegationElimination 的回复简化为可以在管道中使用的三行代码:

    import csv
    import json
    import sys
    
    for row in csv.DictReader(sys.stdin):
        json.dump(row, sys.stdout)
        sys.stdout.write('\n')
    

    【讨论】:

    • 有人记得糟糕的 perl oneliner 吗? python -c 'import json;import csv;out=open("jsonfilename","w");c=csv.DictReader(open("csvfilename"));[(json.dump(x,out),out.write("\n")) for x in c]
    【解决方案7】:

    如何使用 Pandas 将 csv 文件读入 DataFrame (pd.read_csv),然后根据需要操作列(删除它们或更新值),最后将 DataFrame 转换回 JSON (pd.DataFrame.to_json)。

    注意:我还没有检查过它的效率如何,但这绝对是操作大型 csv 并将其转换为 json 的最简单方法之一。

    【讨论】:

      【解决方案8】:

      我看到这是旧的,但我需要来自 SingleNegationElimination 的代码,但是我遇到了包含非 utf-8 字符的数据的问题。这些出现在我不太关心的领域,所以我选择忽略它们。然而,这需要一些努力。我是 python 新手,所以经过反复试验,我让它工作了。该代码是 SingleNegationElimination 的副本,带有对 utf-8 的额外处理。我试着用https://docs.python.org/2.7/library/csv.html 做,但最后放弃了。以下代码有效。

      import csv, json
      
      csvfile = open('file.csv', 'r')
      jsonfile = open('file.json', 'w')
      
      fieldnames = ("Scope","Comment","OOS Code","In RMF","Code","Status","Name","Sub Code","CAT","LOB","Description","Owner","Manager","Platform Owner")
      reader = csv.DictReader(csvfile , fieldnames)
      
      code = ''
      for row in reader:
          try:
              print('+' + row['Code'])
              for key in row:
                  row[key] = row[key].decode('utf-8', 'ignore').encode('utf-8')      
              json.dump(row, jsonfile)
              jsonfile.write('\n')
          except:
              print('-' + row['Code'])
              raise
      

      【讨论】:

        【解决方案9】:

        您可以使用 Pandas DataFrame 来实现这一点,示例如下:

        import pandas as pd
        csv_file = pd.DataFrame(pd.read_csv("path/to/file.csv", sep = ",", header = 0, index_col = False))
        csv_file.to_json("/path/to/new/file.json", orient = "records", date_format = "epoch", double_precision = 10, force_ascii = True, date_unit = "ms", default_handler = None)
        

        【讨论】:

        • 简洁明了
        【解决方案10】:
        import csv
        import json
        
        file = 'csv_file_name.csv'
        json_file = 'output_file_name.json'
        
        #Read CSV File
        def read_CSV(file, json_file):
            csv_rows = []
            with open(file) as csvfile:
                reader = csv.DictReader(csvfile)
                field = reader.fieldnames
                for row in reader:
                    csv_rows.extend([{field[i]:row[field[i]] for i in range(len(field))}])
                convert_write_json(csv_rows, json_file)
        
        #Convert csv data into json
        def convert_write_json(data, json_file):
            with open(json_file, "w") as f:
                f.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': '))) #for pretty
                f.write(json.dumps(data))
        
        
        read_CSV(file,json_file)
        

        Documentation of json.dumps()

        【讨论】:

        • 正确答案,恕我直言。
        • 您必须选择此行:f.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': '))) #for pretty 或此行:f.write(json.dumps(data)) - 不能同时选择两者!
        • 完美运行,返回一个 json 数组
        【解决方案11】:
        def read():
            noOfElem = 200  # no of data you want to import
            csv_file_name = "hashtag_donaldtrump.csv"  # csv file name
            json_file_name = "hashtag_donaldtrump.json"  # json file name
        
            with open(csv_file_name, mode='r') as csv_file:
                csv_reader = csv.DictReader(csv_file)
                with open(json_file_name, 'w') as json_file:
                    i = 0
                    json_file.write("[")
                    
                    for row in csv_reader:
                        i = i + 1
                        if i == noOfElem:
                            json_file.write("]")
                            return
        
                        json_file.write(json.dumps(row))
        
                        if i != noOfElem - 1:
                            json_file.write(",")
        
        

        改变以上三个参数,一切就搞定了。

        【讨论】:

          【解决方案12】:

          使用 pandas 和 json 库:

          import pandas as pd
          import json
          filepath = "inputfile.csv"
          output_path = "outputfile.json"
          
          df = pd.read_csv(filepath)
          
          # Create a multiline json
          json_list = json.loads(df.to_json(orient = "records"))
          
          with open(output_path, 'w') as f:
              for item in json_list:
                  f.write("%s\n" % item)
          

          【讨论】:

            猜你喜欢
            • 2019-02-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-18
            • 1970-01-01
            • 2019-11-01
            • 2021-01-31
            相关资源
            最近更新 更多