json转换成表格 - python写入csv




我如何将JSON转换为CSV? (10)

JSON可以表示各种各样的数据结构 - 一个JS“对象”大致类似于Python字典(带有字符串键),一个JS“数组”类似于Python列表,只要最终的“叶子“元素是数字或字符串。

CSV基本上只能表示一个二维表格 - 可选地包含第一行“标题”,即“列名称”,它可以使表格可解释为一系列的字典,而不是正常的解释,列表列表(再次,“叶”元素可以是数字或字符串)。

因此,在一般情况下,您无法将任意JSON结构转换为CSV。 在一些特殊情况下,您可以(不需要进一步嵌套的数组的数组;所有对象的数组都具有完全相同的键)。 哪种特殊情况适用于您的问题? 解决方案的细节取决于你有哪些特殊情况。 考虑到你甚至没有提到哪一个适用的令人惊讶的事实,我怀疑你可能没有考虑过这个约束,实际上这两个可用的情况都不适用,而且你的问题是不可能解决的。 但请澄清!

我有一个JSON文件,我想转换为CSV文件。 我如何用Python做到这一点?

我试过了:

import json
import csv

f = open('data.json')
data = json.load(f)
f.close()
f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
    f.writerow(item)

f.close()

但是,它没有工作。 我正在使用Django,我收到的错误是:

file' object has no attribute 'writerow'

所以,我尝试了以下内容:

import json
import csv

f = open('data.json')
data = json.load(f)
f.close()

f = open('data.csv')
csv_file = csv.writer(f)
for item in data:
    csv_file.writerow(item)

f.close()

然后我得到错误:

sequence expected

示例json文件:

[
  {
    "pk": 22,
    "model": "auth.permission",
    "fields": {
      "codename": "add_logentry",
      "name": "Can add log entry",
      "content_type": 8
    }
  },
  {
    "pk": 23,
    "model": "auth.permission",
    "fields": {
      "codename": "change_logentry",
      "name": "Can change log entry",
      "content_type": 8
    }
  },
  {
    "pk": 24,
    "model": "auth.permission",
    "fields": {
      "codename": "delete_logentry",
      "name": "Can delete log entry",
      "content_type": 8
    }
  },
  {
    "pk": 4,
    "model": "auth.permission",
    "fields": {
      "codename": "add_group",
      "name": "Can add group",
      "content_type": 2
    }
  },
  {
    "pk": 10,
    "model": "auth.permission",
    "fields": {
      "codename": "add_message",
      "name": "Can add message",
      "content_type": 4
    }
  }
]

使用csv.DictWriter()很容易,详细的实现可以像这样:

def read_json(filename):
    return json.loads(open(filename).read())
def write_csv(data,filename):
    with open(filename) as outf:
        writer = csv.DictWriter(outf, data[0].keys())
        writer.writeheader()
        for row in data:
            writer.writerow(row)
# implement
write_csv(read_json('test.json'), 'output.csv')

请注意,这假定所有的JSON对象都具有相同的字段。

这里是可以帮助你的reference


借助pandas library这与使用两个命令一样简单!

pandas.read_json()

将JSON字符串转换为熊猫物件(序列或数据框)。 然后,假设结果存储为df

df.to_csv()

它可以返回一个字符串或直接写入一个csv文件。

根据以前答案的详细程度,我们都应该感谢大熊猫的捷径。


假设您的JSON数据位于名为data.json的文件中,该代码应该适用于您。

import json
import csv

with open("data.json") as file:
    data = json.load(file)

with open("data.csv", "w") as file:
    csv_file = csv.writer(file)
    for item in data:
        csv_file.writerow([item['pk'], item['model']] + item['fields'].values())

我不确定这个问题是否已经解决,但让我粘贴我所做的参考。

首先,你的JSON具有嵌套的对象,所以它通常不能直接转换为CSV。 你需要改变这样的东西:

{
    "pk": 22,
    "model": "auth.permission",
    "codename": "add_logentry",
    "content_type": 8,
    "name": "Can add log entry"
},
......]

这里是我的代码来从中生成CSV:

import csv
import json

x = """[
    {
        "pk": 22,
        "model": "auth.permission",
        "fields": {
            "codename": "add_logentry",
            "name": "Can add log entry",
            "content_type": 8
        }
    },
    {
        "pk": 23,
        "model": "auth.permission",
        "fields": {
            "codename": "change_logentry",
            "name": "Can change log entry",
            "content_type": 8
        }
    },
    {
        "pk": 24,
        "model": "auth.permission",
        "fields": {
            "codename": "delete_logentry",
            "name": "Can delete log entry",
            "content_type": 8
        }
    }
]"""

x = json.loads(x)

f = csv.writer(open("test.csv", "wb+"))

# Write CSV Header, If you dont need that, remove this line
f.writerow(["pk", "model", "codename", "name", "content_type"])

for x in x:
    f.writerow([x["pk"],
                x["model"],
                x["fields"]["codename"],
                x["fields"]["name"],
                x["fields"]["content_type"]])

你会得到如下输出:

pk,model,codename,name,content_type
22,auth.permission,add_logentry,Can add log entry,8
23,auth.permission,change_logentry,Can change log entry,8
24,auth.permission,delete_logentry,Can delete log entry,8

我假设你的JSON文件将解码成一个字典列表。 首先,我们需要一个可以压扁JSON对象的函数:

def flattenjson( b, delim ):
    val = {}
    for i in b.keys():
        if isinstance( b[i], dict ):
            get = flattenjson( b[i], delim )
            for j in get.keys():
                val[ i + delim + j ] = get[j]
        else:
            val[i] = b[i]

    return val

在您的JSON对象上运行此片段的结果:

flattenjson( {
    "pk": 22, 
    "model": "auth.permission", 
    "fields": {
      "codename": "add_message", 
      "name": "Can add message", 
      "content_type": 8
    }
  }, "__" )

{
    "pk": 22, 
    "model": "auth.permission', 
    "fields__codename": "add_message", 
    "fields__name": "Can add message", 
    "fields__content_type": 8
}

将此函数应用于JSON对象的输入数组中的每个词典后:

input = map( lambda x: flattenjson( x, "__" ), input )

并找到相关的列名称:

columns = [ x for row in input for x in row.keys() ]
columns = list( set( columns ) )

通过csv模块运行它并不困难:

with open( fname, 'wb' ) as out_file:
    csv_w = csv.writer( out_file )
    csv_w.writerow( columns )

    for i_r in input:
        csv_w.writerow( map( lambda x: i_r.get( x, "" ), columns ) )

我希望这有帮助!


我知道自问这个问题以来已经有很长时间了,但我想我可以添加到其他人的答案中,并分享一篇博文,我想以一种非常简洁的方式解释解决方案。

这是link

打开一个文件写入

employ_data = open('/tmp/EmployData.csv', 'w')

创建csv编写器对象

csvwriter = csv.writer(employ_data)
count = 0
for emp in emp_data:
      if count == 0:
             header = emp.keys()
             csvwriter.writerow(header)
             count += 1
      csvwriter.writerow(emp.values())

确保关闭文件以保存内容

employ_data.close()

我简单的方法来解决这个问题:

创建一个新的Python文件,如:json_to_csv.py

添加以下代码:

import csv, json, sys
#if you are not using utf-8 files, remove the next line
sys.setdefaultencoding("UTF-8")
#check if you pass the input file and output file
if sys.argv[1] is not None and sys.argv[2] is not None:

    fileInput = sys.argv[1]
    fileOutput = sys.argv[2]

    inputFile = open(fileInput)
    outputFile = open(fileOutput, 'w')
    data = json.load(inputFile)
    inputFile.close()

    output = csv.writer(outputFile)

    output.writerow(data[0].keys())  # header row

    for row in data:
        output.writerow(row.values())

添加此代码后,保存该文件并在终端上运行:

python json_to_csv.py input.txt output.csv

我希望这对你有所帮助。

再见!


由于数据看起来是字典格式,因此看起来应该使用csv.DictWriter()实际输出具有适当标题信息的行。 这应该允许转换处理更容易一些。 然后,fieldnames参数将正确设置顺序,而第一行的输出作为标题将允许它在稍后被csv.DictReader()读取和处理。

例如,Mike Repass用过

output = csv.writer(sys.stdout)

output.writerow(data[0].keys())  # header row

for row in data:
  output.writerow(row.values())

但是,只需将初始设置更改为output = csv.DictWriter(filesetting,fieldnames = data [0] .keys())

请注意,由于未定义字典中元素的顺序,因此可能必须显式创建字段名称条目。 一旦你这样做,作家就会工作。 写入然后按原来的方式工作。


这不是一个非常聪明的方式,但我有同样的问题,这对我有用:

import csv

f = open('data.json')
data = json.load(f)
f.close()

new_data = []

for i in data:
   flat = {}
   names = i.keys()
   for n in names:
      try:
         if len(i[n].keys()) > 0:
            for ii in i[n].keys():
               flat[n+"_"+ii] = i[n][ii]
      except:
         flat[n] = i[n]
   new_data.append(flat)  

f = open(filename, "r")
writer = csv.DictWriter(f, new_data[0].keys())
writer.writeheader()
for row in new_data:
   writer.writerow(row)
f.close()






csv