Làm cách nào tôi có thể chuyển đổi JSON sang CSV?


184

Tôi có một tệp JSON tôi muốn chuyển đổi thành tệp CSV. Làm thế nào tôi có thể làm điều này với Python?

Tôi đã thử:

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()

Tuy nhiên, nó đã không hoạt động. Tôi đang sử dụng Django và lỗi tôi nhận được là:

file' object has no attribute 'writerow'

Sau đó tôi đã thử như sau:

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)  # ← changed

f.close()

Sau đó tôi nhận được lỗi:

sequence expected

Tệp json mẫu:

[{
        "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
        }
    }
]

1
csv_file.writerow (item) yêu cầu mục phải là một danh sách đơn giản của chuỗi hoặc số. Hãy thử chuyển đổi từng đối tượng json thành một danh sách phẳng, như {"pk": 22, "model": "authÿ"} sẽ trở thành [22, auth-01].
Ức chế lửa

1
Một cách tiếp cận đơn giản cho việc này đang được sử dụng jq, như được mô tả ở đây: stackoverflow.com/questions/32960857/iêu
Micah Elliott

Thay thế bên thứ 3: json-csv.com (để chuyển đổi một lần) hoặc json-csv.com/api để tự động hóa với Python. Đây là một giải pháp đơn giản cho các cấu trúc JSON phức tạp hơn.
Stack Man

Câu trả lời:


129

Đầu tiên, JSON của bạn có các đối tượng lồng nhau, do đó, thông thường không thể chuyển đổi trực tiếp sang CSV. Bạn cần thay đổi điều đó thành một cái gì đó như thế này:

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

Đây là mã của tôi để tạo CSV từ đó:

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"]])

Bạn sẽ nhận được đầu ra là:

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

2
đây là công việc nhưng xin lỗi trước khi tôi có thể nhận được một cái gì đó không khó i mã điều nó id tốt hơn tôi có thể sử dụng f.writerow (a) và a là một số variabel mà tôi tuyên bố trước nhờ trước
little_fish

Đối với tôi điều này hoạt động gần như hoàn hảo. Trong CSV đã xuất, một số trường được bao quanh bởi [u'']. Cách giải quyết (không xử lý hậu kỳ) là gì? nếu có một ... :)
Dror

3
Dưới đây tôi đã chỉ ra một cách để làm điều đó một cách tổng quát hơn mà không cần phải viết mã cứng
Alec McGail

4
này, tôi đã thử cái này nhưng tôi nhận được TypeError: a bytes-like object is required, not 'str'tạif.writerow(['pk', 'model', 'codename', 'name', 'content_type'])
Aditya Hariharan

8
cho dòng thay đổi python3 bằng cách mở tệp csv thànhf = csv.writer(open("test.csv", "w", newline=''))
PiotrK

118

Với pandas thư viện , việc này dễ như sử dụng hai lệnh!

pandas.read_json()

Để chuyển đổi một chuỗi JSON thành một đối tượng gấu trúc (một chuỗi hoặc khung dữ liệu). Sau đó, giả sử kết quả được lưu trữ dưới dạng df:

df.to_csv()

Có thể trả về một chuỗi hoặc ghi trực tiếp vào tệp csv.

Dựa trên tính dài dòng của các câu trả lời trước đó, tất cả chúng ta nên cảm ơn gấu trúc vì lối tắt.


1
Đây là một câu trả lời tuyệt vời (+1) - rất đơn giản và .to_csv()thực sự mạnh mẽ (ví dụ như lọc cột miễn phí). Tôi cần học gấu trúc.
WoJ

3
Như đã chỉ ra, câu trả lời này không hoạt động đối với dữ liệu trong câu hỏi này. orient='records'phải được đặt, nhưng mỗi hàng fieldsvẫn sẽ là một dict, đó không phải là những gì OP yêu cầu.
Trenton McKinney

90

Tôi giả sử rằng tệp JSON của bạn sẽ giải mã thành một danh sách từ điển. Đầu tiên chúng ta cần một hàm sẽ làm phẳng các đối tượng 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

Kết quả của việc chạy đoạn mã này trên đối tượng JSON của bạn:

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
}

Sau khi áp dụng hàm này cho từng dict trong mảng đầu vào của các đối tượng JSON:

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

và tìm tên cột có liên quan:

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

Không khó để chạy nó thông qua mô-đun 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 ) )

Tôi hi vọng cái này giúp được!


Sử dụng Python 3.6, tôi phải tạo một danh sách JSON được làm phẳng để vòng lặp cuối hoạt động: "input = list (map (lambda x: flattenjson (x," __ "), input))". Tôi không hiểu tại sao lặp đi lặp lại là không đủ. Tôi cũng phải chỉ định mã hóa khi mở tệp đầu ra vì dữ liệu của tôi sử dụng UTF8. Nó chắc chắn có ích, cảm ơn bạn !!
Alexis R

Điều này thật tuyệt, cảm ơn Alec! Tôi đã sửa đổi nó để hoạt động với nhiều cấp độ lồng nhau: stackoverflow.com/a/57228641/473201
phreakhead

35

JSON có thể đại diện cho một loạt các cấu trúc dữ liệu - một "đối tượng" JS gần giống như một lệnh Python (với các khóa chuỗi), một mảng "JS" gần giống như một danh sách Python và bạn có thể lồng chúng miễn là cuối cùng " yếu tố lá "là số hoặc chuỗi.

Về cơ bản, CSV chỉ có thể biểu thị một bảng 2 chiều - tùy ý có một hàng "tiêu đề" đầu tiên, nghĩa là "tên cột", có thể làm cho bảng có thể hiểu được như một danh sách các ký tự, thay vì cách hiểu thông thường, một danh sách danh sách (một lần nữa, các phần tử "lá" có thể là số hoặc chuỗi).

Vì vậy, trong trường hợp chung, bạn không thể dịch cấu trúc JSON tùy ý sang CSV. Trong một vài trường hợp đặc biệt, bạn có thể (mảng các mảng không có lồng nhau nữa; mảng các đối tượng mà tất cả đều có cùng khóa). Trường hợp đặc biệt nào, nếu có, áp dụng cho vấn đề của bạn? Các chi tiết của giải pháp phụ thuộc vào trường hợp đặc biệt mà bạn có. Với một sự thật đáng kinh ngạc là bạn thậm chí không đề cập đến cái nào áp dụng, tôi nghi ngờ bạn có thể đã không xem xét các ràng buộc, thực tế không áp dụng được trường hợp nào và vấn đề của bạn là không thể giải quyết. Nhưng làm ơn làm rõ!


31

Một giải pháp chung giúp dịch bất kỳ danh sách json nào của các đối tượng phẳng sang csv.

Truyền tệp input.json làm đối số đầu tiên trên dòng lệnh.

import csv, json, sys

input = open(sys.argv[1])
data = json.load(input)
input.close()

output = csv.writer(sys.stdout)

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

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

2
Một nhận xét quan trọng - mã này lấy các cột / tiêu đề từ các trường ở hàng đầu tiên. Nếu dữ liệu json của bạn có các cột 'lởm chởm', tức là hàng1 có 5 cột nhưng hàng2 có 6 cột, thì bạn cần thực hiện lần đầu tiên qua dữ liệu để lấy tổng số tất cả các cột và sử dụng làm tiêu đề.
Mike Repass

Với dữ liệu tôi có, đây là một phần tuyệt vời của giải pháp tôi cần, vì JSON của tôi không bị lởm chởm, nó hoạt động tuyệt vời với một số điều chỉnh nhỏ cho đầu ra vì tôi đang chạy nó trong một tập lệnh hiện có.
MichaelF

1
Mã này cũng giả định rằng các giá trị sẽ được xuất theo thứ tự giống như các khóa trong hàng tiêu đề. Trong khi điều đó có thể đã làm việc may mắn, nó không có nghĩa là được đảm bảo.
RyanHennig

Bắt lỗi mã hóa. Bất kỳ ý tưởng làm thế nào để thêm mã hóa vào utf-8?
Elad Tabak

25

Mã này sẽ phù hợp với bạn, giả sử rằng dữ liệu JSON của bạn nằm trong một tệp được gọi 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:
        fields = list(item['fields'].values())
        csv_file.writerow([item['pk'], item['model']] + fields)

1
Hmmm, không - csv_file.writerow(tất nhiên là không có f.writerow, tôi giả sử bạn đã mắc lỗi đánh máy ở đó!) Muốn có một chuỗi, không phải là một lệnh - và trong ví dụ của bạn, mỗi mục là một lệnh. Điều này sẽ làm việc cho trường hợp đặc biệt KHÁC, như tôi đã xác định trong câu trả lời của mình - nơi tệp JSON có một mảng các mảng; nó không hoạt động đối với một loạt các đối tượng, đó là trường hợp đặc biệt mà bạn dường như đang cố gắng giải quyết (điều đó đòi hỏi một csv.DictWriter- và tất nhiên bạn cần trích xuất tên trường và quyết định theo thứ tự để khởi tạo nó ! -).
Alex Martelli

@DanLoewenherz Điều đó không hoạt động trên các phiên bản Python gần đây. LoạiError: chỉ có thể ghép danh sách (không phải "dict_values") vào danh sách
Apolo Radomer

18

Nó sẽ dễ sử dụng csv.DictWriter(), việc thực hiện chi tiết có thể như sau:

def read_json(filename):
    return json.loads(open(filename).read())
def write_csv(data,filename):
    with open(filename, 'w+') 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')

Lưu ý rằng điều này giả định rằng tất cả các đối tượng JSON của bạn có cùng các trường.

Đây là tài liệu tham khảo có thể giúp bạn.


Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi. - Từ đánh giá
Mathieu

3
@purplepsycho Tôi tìm thấy câu trả lời này với một downvote, nó chỉ xứng đáng được liên kết. Người dùng mới, những người có thể đã không biết rằng chỉ liên kết không phải là một câu trả lời tốt, đã sửa nó. Tôi ủng hộ; có lẽ bạn cũng có thể, để khuyến khích người dùng mới tiếp tục tham gia vào cộng đồng của chúng tôi?
Mawg nói rằng phục hồi Monica

6

Tôi đã gặp rắc rối với giải pháp đề xuất của Dan , nhưng điều này hiệu quả với tôi:

import json
import csv 

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

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

for item in data:
  f.writerow([item['pk'], item['model']] + item['fields'].values())

Trong đó "test.json" chứa các mục sau:

[ 
{"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ảy ra lỗi khi thử chương trình trên dữ liệu mẫu của bạn C: \ curl> python json2csv.py TracBack (cuộc gọi gần đây nhất): Tệp "json2csv.py", dòng 11, trong <module> f.writerow ([item ['pk '], mục [' model ']] + item [' field ']. value ()) TypeError: chỉ có thể ghép danh sách (không phải "dict_values") vào danh sách
Mian Asbat Ahmad

Đã thử lại lần nữa trong Python 2.7.9 và nó hoạt động tốt với tôi.
Amanda

6

Sử dụng json_normalizetừ pandas:

  • Cho dữ liệu được cung cấp, trong một tệp có tên test.json
  • encoding='utf-8' có thể không cần thiết
  • Đoạn mã sau tận dụng pathlibthư viện
    • .open là một phương pháp của pathlib
    • Cũng hoạt động với các đường dẫn không phải Windows
import pandas as pd
# As of Pandas 1.01, json_normalize as pandas.io.json.json_normalize is deprecated and is now exposed in the top-level namespace.
# from pandas.io.json import json_normalize
from pathlib import Path
import json

# set path to file
p = Path(r'c:\some_path_to_file\test.json')

# read json
with p.open('r', encoding='utf-8') as f:
    data = json.loads(f.read())

# create dataframe
df = pd.json_normalize(data)

# dataframe view
 pk            model  fields.codename           fields.name  fields.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
  4  auth.permission        add_group         Can add group                    2
 10  auth.permission      add_message       Can add message                    4

# save to csv
df.to_csv('test.csv', index=False, encoding='utf-8')

Đầu ra CSV:

pk,model,fields.codename,fields.name,fields.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
4,auth.permission,add_group,Can add group,2
10,auth.permission,add_message,Can add message,4

Các tài nguyên khác cho các đối tượng JSON được lồng nhiều hơn:


4

Như đã đề cập trong các câu trả lời trước, khó khăn trong việc chuyển đổi json thành csv là do một tệp json có thể chứa các từ điển lồng nhau và do đó là một cấu trúc dữ liệu đa chiều trong câu csv là cấu trúc dữ liệu 2D. Tuy nhiên, một cách hay để biến cấu trúc đa chiều thành csv là có nhiều csv liên kết với nhau bằng các khóa chính.

Trong ví dụ của bạn, đầu ra csv đầu tiên có các cột "pk", "model", "field" làm cột của bạn. Các giá trị cho "pk" và "model" rất dễ nhận được nhưng vì cột "trường" chứa từ điển, nên nó phải là csv của chính nó và vì "tên mã" xuất hiện là khóa chính, bạn có thể sử dụng làm đầu vào cho "các trường" để hoàn thành csv đầu tiên. Cvv thứ hai chứa từ điển từ cột "các trường" với tên mã là khóa chính có thể được sử dụng để liên kết 2 csv với nhau.

Đây là một giải pháp cho tệp json của bạn để chuyển đổi một từ điển lồng nhau thành 2 csvs.

import csv
import json

def readAndWrite(inputFileName, primaryKey=""):
    input = open(inputFileName+".json")
    data = json.load(input)
    input.close()

    header = set()

    if primaryKey != "":
        outputFileName = inputFileName+"-"+primaryKey
        if inputFileName == "data":
            for i in data:
                for j in i["fields"].keys():
                    if j not in header:
                        header.add(j)
    else:
        outputFileName = inputFileName
        for i in data:
            for j in i.keys():
                if j not in header:
                    header.add(j)

    with open(outputFileName+".csv", 'wb') as output_file:
        fieldnames = list(header)
        writer = csv.DictWriter(output_file, fieldnames, delimiter=',', quotechar='"')
        writer.writeheader()
        for x in data:
            row_value = {}
            if primaryKey == "":
                for y in x.keys():
                    yValue = x.get(y)
                    if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
                        row_value[y] = str(yValue).encode('utf8')
                    elif type(yValue) != dict:
                        row_value[y] = yValue.encode('utf8')
                    else:
                        if inputFileName == "data":
                            row_value[y] = yValue["codename"].encode('utf8')
                            readAndWrite(inputFileName, primaryKey="codename")
                writer.writerow(row_value)
            elif primaryKey == "codename":
                for y in x["fields"].keys():
                    yValue = x["fields"].get(y)
                    if type(yValue) == int or type(yValue) == bool or type(yValue) == float or type(yValue) == list:
                        row_value[y] = str(yValue).encode('utf8')
                    elif type(yValue) != dict:
                        row_value[y] = yValue.encode('utf8')
                writer.writerow(row_value)

readAndWrite("data")

4

Tôi biết đã lâu rồi kể từ khi câu hỏi này được hỏi nhưng tôi nghĩ tôi có thể thêm vào câu trả lời của người khác và chia sẻ một bài đăng trên blog mà tôi nghĩ giải thích giải pháp một cách rất súc tích.

Đây là liên kết

Mở một tập tin để viết

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

Tạo đối tượng nhà văn 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())

Đảm bảo đóng tệp để lưu nội dung

employ_data.close()

3

Đó không phải là một cách rất thông minh để làm điều đó, nhưng tôi đã có cùng một vấn đề và điều này đã làm việc cho tôi:

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()

3

Câu trả lời của Alec là tuyệt vời, nhưng nó không hoạt động trong trường hợp có nhiều cấp độ lồng nhau. Đây là một phiên bản sửa đổi hỗ trợ nhiều cấp độ lồng nhau. Nó cũng làm cho tên tiêu đề đẹp hơn một chút nếu đối tượng lồng nhau đã chỉ định khóa riêng của nó (ví dụ: dữ liệu Firebase Analytics / BigTable / BigQuery):

"""Converts JSON with nested fields into a flattened CSV file.
"""

import sys
import json
import csv
import os

import jsonlines

from orderedset import OrderedSet

# from https://stackoverflow.com/a/28246154/473201
def flattenjson( b, prefix='', delim='/', val=None ):
  if val == None:
    val = {}

  if isinstance( b, dict ):
    for j in b.keys():
      flattenjson(b[j], prefix + delim + j, delim, val)
  elif isinstance( b, list ):
    get = b
    for j in range(len(get)):
      key = str(j)

      # If the nested data contains its own key, use that as the header instead.
      if isinstance( get[j], dict ):
        if 'key' in get[j]:
          key = get[j]['key']

      flattenjson(get[j], prefix + delim + key, delim, val)
  else:
    val[prefix] = b

  return val

def main(argv):
  if len(argv) < 2:
    raise Error('Please specify a JSON file to parse')

  filename = argv[1]
  allRows = []
  fieldnames = OrderedSet()
  with jsonlines.open(filename) as reader:
    for obj in reader:
      #print obj
      flattened = flattenjson(obj)
      #print 'keys: %s' % flattened.keys()
      fieldnames.update(flattened.keys())
      allRows.append(flattened)

  outfilename = filename + '.csv'
  with open(outfilename, 'w') as file:
    csvwriter = csv.DictWriter(file, fieldnames=fieldnames)
    csvwriter.writeheader()
    for obj in allRows:
      csvwriter.writerow(obj)



if __name__ == '__main__':
  main(sys.argv)

2

Điều này hoạt động tương đối tốt. Nó làm phẳng json để ghi nó vào một tệp csv. Các yếu tố lồng nhau được quản lý :)

Đó là cho python 3

import json

o = json.loads('your json string') # Be careful, o must be a list, each of its objects will make a line of the csv.

def flatten(o, k='/'):
    global l, c_line
    if isinstance(o, dict):
        for key, value in o.items():
            flatten(value, k + '/' + key)
    elif isinstance(o, list):
        for ov in o:
            flatten(ov, '')
    elif isinstance(o, str):
        o = o.replace('\r',' ').replace('\n',' ').replace(';', ',')
        if not k in l:
            l[k]={}
        l[k][c_line]=o

def render_csv(l):
    ftime = True

    for i in range(100): #len(l[list(l.keys())[0]])
        for k in l:
            if ftime :
                print('%s;' % k, end='')
                continue
            v = l[k]
            try:
                print('%s;' % v[i], end='')
            except:
                print(';', end='')
        print()
        ftime = False
        i = 0

def json_to_csv(object_list):
    global l, c_line
    l = {}
    c_line = 0
    for ov in object_list : # Assumes json is a list of objects
        flatten(ov)
        c_line += 1
    render_csv(l)

json_to_csv(o)

thưởng thức.


Tập tin .csv không được tạo, thay vào đó, văn bản csv được xuất ra bàn điều khiển. Ngoài ra, json.loadskhông hoạt động, tôi đã làm cho nó hoạt động json.load, mang lại một đối tượng danh sách. Thứ ba, các yếu tố lồng nhau đã bị mất.
ZygD

2

Cách đơn giản của tôi để giải quyết điều này:

Tạo một tệp Python mới như: json_to_csv.py

Thêm mã này:

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())

Sau khi thêm mã này, lưu tệp và chạy tại thiết bị đầu cuối:

python json_to_csv.py input.txt output.csv

Tôi hy vọng điều này sẽ giúp bạn.

HẸN GẶP LẠI SAU!


1
Mẫu này hoạt động như một nét duyên dáng! cảm ơn vì đã chia sẻ, tôi đã có thể chuyển đổi tập tin json của mình thành CSV bằng cách sử dụng tập lệnh python này
Mostafa

2

Đáng ngạc nhiên, tôi thấy rằng cho đến nay không có câu trả lời nào được đăng ở đây xử lý chính xác tất cả các tình huống có thể xảy ra (ví dụ: các ký tự lồng nhau, danh sách lồng nhau, Không có giá trị, v.v.).

Giải pháp này sẽ hoạt động trên tất cả các kịch bản:

def flatten_json(json):
    def process_value(keys, value, flattened):
        if isinstance(value, dict):
            for key in value.keys():
                process_value(keys + [key], value[key], flattened)
        elif isinstance(value, list):
            for idx, v in enumerate(value):
                process_value(keys + [str(idx)], v, flattened)
        else:
            flattened['__'.join(keys)] = value

    flattened = {}
    for key in json.keys():
        process_value([key], json[key], flattened)
    return flattened

2

Thử cái này

import csv, json, sys

input = open(sys.argv[1])
data = json.load(input)
input.close()

output = csv.writer(sys.stdout)

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

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

2

Mã này hoạt động cho bất kỳ tệp json nào

# -*- coding: utf-8 -*-
"""
Created on Mon Jun 17 20:35:35 2019
author: Ram
"""

import json
import csv

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



# create the csv writer object
pt_data1 = open('pt_data1.csv', 'w')
csvwriter = csv.writer(pt_data1)

count = 0

for pt in data:

      if count == 0:

             header = pt.keys()

             csvwriter.writerow(header)

             count += 1

      csvwriter.writerow(pt.values())

pt_data1.close()

1

Câu trả lời của Alec McGail đã sửa đổi để hỗ trợ JSON với các danh sách bên trong

    def flattenjson(self, mp, delim="|"):
            ret = []
            if isinstance(mp, dict):
                    for k in mp.keys():
                            csvs = self.flattenjson(mp[k], delim)
                            for csv in csvs:
                                    ret.append(k + delim + csv)
            elif isinstance(mp, list):
                    for k in mp:
                            csvs = self.flattenjson(k, delim)
                            for csv in csvs:
                                    ret.append(csv)
            else:
                    ret.append(mp)

            return ret

Cảm ơn!


1
import json,csv
t=''
t=(type('a'))
json_data = []
data = None
write_header = True
item_keys = []
try:
with open('kk.json') as json_file:
    json_data = json_file.read()

    data = json.loads(json_data)
except Exception as e:
    print( e)

with open('bar.csv', 'at') as csv_file:
    writer = csv.writer(csv_file)#, quoting=csv.QUOTE_MINIMAL)
    for item in data:
        item_values = []
        for key in item:
            if write_header:
                item_keys.append(key)
            value = item.get(key, '')
            if (type(value)==t):
                item_values.append(value.encode('utf-8'))
            else:
                item_values.append(value)
        if write_header:
            writer.writerow(item_keys)
            write_header = False
        writer.writerow(item_values)

1

Nếu chúng ta xem xét ví dụ dưới đây để chuyển đổi tệp định dạng json sang tệp được định dạng csv.

{
 "item_data" : [
      {
        "item": "10023456",
        "class": "100",
        "subclass": "123"
      }
      ]
}

Đoạn mã dưới đây sẽ chuyển đổi tệp json (data3.json) thành tệp csv (data3.csv).

import json
import csv
with open("/Users/Desktop/json/data3.json") as file:
    data = json.load(file)
    file.close()
    print(data)

fname = "/Users/Desktop/json/data3.csv"

with open(fname, "w", newline='') as file:
    csv_file = csv.writer(file)
    csv_file.writerow(['dept',
                       'class',
                       'subclass'])
    for item in data["item_data"]:
         csv_file.writerow([item.get('item_data').get('dept'),
                            item.get('item_data').get('class'),
                            item.get('item_data').get('subclass')])

Đoạn mã được đề cập ở trên đã được thực thi trong pycharm được cài đặt cục bộ và nó đã chuyển đổi thành công tệp json thành tệp csv. Hy vọng điều này sẽ giúp chuyển đổi các tập tin.


0

Vì dữ liệu dường như ở định dạng từ điển, nên có vẻ như bạn thực sự nên sử dụng csv.DictWriter () để thực sự xuất các dòng có thông tin tiêu đề phù hợp. Điều này sẽ cho phép chuyển đổi được xử lý phần nào dễ dàng hơn. Tham số tên trường sau đó sẽ thiết lập thứ tự đúng trong khi đầu ra của dòng đầu tiên là các tiêu đề sẽ cho phép nó được đọc và xử lý sau bởi csv.DictReader ().

Ví dụ, Mike Repass đã sử dụng

output = csv.writer(sys.stdout)

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

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

Tuy nhiên, chỉ cần thay đổi thiết lập ban đầu thành output = csv.DictWriter (tập tin, tên trường = dữ liệu [0] .keys ())

Lưu ý rằng vì thứ tự các thành phần trong từ điển không được xác định, bạn có thể phải tạo các mục nhập tên trường một cách rõ ràng. Một khi bạn làm điều đó, nhà văn sẽ làm việc. Các văn bản sau đó làm việc như hiển thị ban đầu.


0

Thật không may, tôi không có tiếng tăm để đóng góp nhỏ cho câu trả lời tuyệt vời @Alec McGail. Tôi đã sử dụng Python3 và tôi cần chuyển đổi bản đồ thành danh sách theo nhận xét @Alexis R.

Bổ sung Tôi đã tìm thấy trình soạn thảo csv đang thêm CR vào tệp (Tôi có một dòng trống cho mỗi dòng có dữ liệu bên trong tệp csv). Giải pháp rất dễ dàng sau câu trả lời @Jason R. Coombs cho chủ đề này: CSV trong Python thêm một lợi nhuận vận chuyển bổ sung

Bạn chỉ cần thêm tham số lineterminator = '\ n' vào csv.writer. Nó sẽ là:csv_w = csv.writer( out_file, lineterminator='\n' )


0

Bạn có thể sử dụng mã này để chuyển đổi tệp json thành tệp csv Sau khi đọc tệp, tôi đang chuyển đổi đối tượng sang khung dữ liệu gấu trúc và sau đó lưu tệp này vào tệp CSV

import os
import pandas as pd
import json
import numpy as np

data = []
os.chdir('D:\\Your_directory\\folder')
with open('file_name.json', encoding="utf8") as data_file:    
     for line in data_file:
        data.append(json.loads(line))

dataframe = pd.DataFrame(data)        
## Saving the dataframe to a csv file
dataframe.to_csv("filename.csv", encoding='utf-8',index= False)

điều này không đưa các trường con (chẳng hạn như "các trường" trong ví dụ) vào tài khoản - đối tượng phụ nằm trong một cột thay vì nội dung của nó cũng được tách thành các cột riêng lẻ.
Cũi

0

Tôi có thể đến bữa tiệc muộn, nhưng tôi nghĩ, tôi đã xử lý vấn đề tương tự. Tôi đã có một tập tin json trông như thế này

Cấu trúc tệp JSON

Tôi chỉ muốn trích xuất một vài khóa / giá trị từ các tệp json này. Vì vậy, tôi đã viết đoạn mã sau để trích xuất tương tự.

    """json_to_csv.py
    This script reads n numbers of json files present in a folder and then extract certain data from each file and write in a csv file.
    The folder contains the python script i.e. json_to_csv.py, output.csv and another folder descriptions containing all the json files.
"""

import os
import json
import csv


def get_list_of_json_files():
    """Returns the list of filenames of all the Json files present in the folder
    Parameter
    ---------
    directory : str
        'descriptions' in this case
    Returns
    -------
    list_of_files: list
        List of the filenames of all the json files
    """

    list_of_files = os.listdir('descriptions')  # creates list of all the files in the folder

    return list_of_files


def create_list_from_json(jsonfile):
    """Returns a list of the extracted items from json file in the same order we need it.
    Parameter
    _________
    jsonfile : json
        The json file containing the data
    Returns
    -------
    one_sample_list : list
        The list of the extracted items needed for the final csv
    """

    with open(jsonfile) as f:
        data = json.load(f)

    data_list = []  # create an empty list

    # append the items to the list in the same order.
    data_list.append(data['_id'])
    data_list.append(data['_modelType'])
    data_list.append(data['creator']['_id'])
    data_list.append(data['creator']['name'])
    data_list.append(data['dataset']['_accessLevel'])
    data_list.append(data['dataset']['_id'])
    data_list.append(data['dataset']['description'])
    data_list.append(data['dataset']['name'])
    data_list.append(data['meta']['acquisition']['image_type'])
    data_list.append(data['meta']['acquisition']['pixelsX'])
    data_list.append(data['meta']['acquisition']['pixelsY'])
    data_list.append(data['meta']['clinical']['age_approx'])
    data_list.append(data['meta']['clinical']['benign_malignant'])
    data_list.append(data['meta']['clinical']['diagnosis'])
    data_list.append(data['meta']['clinical']['diagnosis_confirm_type'])
    data_list.append(data['meta']['clinical']['melanocytic'])
    data_list.append(data['meta']['clinical']['sex'])
    data_list.append(data['meta']['unstructured']['diagnosis'])
    # In few json files, the race was not there so using KeyError exception to add '' at the place
    try:
        data_list.append(data['meta']['unstructured']['race'])
    except KeyError:
        data_list.append("")  # will add an empty string in case race is not there.
    data_list.append(data['name'])

    return data_list


def write_csv():
    """Creates the desired csv file
    Parameters
    __________
    list_of_files : file
        The list created by get_list_of_json_files() method
    result.csv : csv
        The csv file containing the header only
    Returns
    _______
    result.csv : csv
        The desired csv file
    """

    list_of_files = get_list_of_json_files()
    for file in list_of_files:
        row = create_list_from_json(f'descriptions/{file}')  # create the row to be added to csv for each file (json-file)
        with open('output.csv', 'a') as c:
            writer = csv.writer(c)
            writer.writerow(row)
        c.close()


if __name__ == '__main__':
    write_csv()

Hy vọng điều này có thể giúp cho bạn. Để biết chi tiết về cách mã này hoạt động, bạn có thể kiểm tra ở đây


0

Đây là bản sửa đổi câu trả lời của @ MikeRepass. Phiên bản này ghi CSV vào một tệp và hoạt động cho cả Python 2 và Python 3.

import csv,json
input_file="data.json"
output_file="data.csv"
with open(input_file) as f:
    content=json.load(f)
try:
    context=open(output_file,'w',newline='') # Python 3
except TypeError:
    context=open(output_file,'wb') # Python 2
with context as file:
    writer=csv.writer(file)
    writer.writerow(content[0].keys()) # header row
    for row in content:
        writer.writerow(row.values())
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.