JSON'u CSV'ye nasıl dönüştürebilirim?


184

Bir CSV dosyasına dönüştürmek istediğim bir JSON dosyam var. Bunu Python ile nasıl yapabilirim?

Denedim:

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

Ancak, işe yaramadı. Django kullanıyorum ve aldığım hata:

file' object has no attribute 'writerow'

Sonra aşağıdakileri denedim:

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

Sonra hatayı alıyorum:

sequence expected

Örnek json dosyası:

[{
        "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), öğenin basit bir dize veya sayı listesi olmasını gerektirir. Her json nesnesini {"pk": 22, "model": "auth.permission"} gibi düz bir listeye dönüştürmeyi deneyin [22, auth.permission].
Yangın Söndürme

1
Buna basit bir yaklaşım jqburada açıklandığı gibi kullanmaktadır : stackoverflow.com/questions/32960857/…
Micah Elliott

3. taraf alternatifi: Python ile otomatikleştirmek için json-csv.com (bir kerelik dönüşümler için) veya json-csv.com/api . Bu daha karmaşık JSON yapıları için basit bir çözümdür.
Stack Man

Yanıtlar:


129

İlk olarak, JSON'unuzda iç içe geçmiş nesneler olduğundan normalde doğrudan CSV'ye dönüştürülemez. Bunu böyle bir şeye değiştirmeniz gerekir:

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

İşte ondan CSV oluşturmak için benim kod:

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

Çıkışı aşağıdaki gibi alacaksınız:

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
Bu iş ama üzgünüm önce ben zor kod değil bir şey alabilir miyim daha iyi bir şey i i f.writerow (a) kullanabilirsiniz ve a daha önce teşekkür ederim bazı variabel
little_fish

Benim için bu neredeyse mükemmel çalışıyor. İhraç CSV olarak, alanların bazıları ile çevrilidir [u've ']. (İşleme sonrası) geçici çözüm nedir? Eğer bir tane varsa ... :)
Dror

3
Aşağıda bunu zor kodlamak zorunda kalmadan daha genel bir şekilde yapmanın bir yolunu gösterdim
Alec McGail

4
Hey, ben bu denedim ama alıyorum TypeError: a bytes-like object is required, not 'str'atf.writerow(['pk', 'model', 'codename', 'name', 'content_type'])
Aditya Hariharan

8
cyt dosya açma ile python3 satır değiştirmef = csv.writer(open("test.csv", "w", newline=''))
PiotrK

119

İle pandas kütüphanede , bu iki komutları kullanarak kadar kolaydır!

pandas.read_json()

JSON dizesini bir panda nesnesine (bir seri veya veri çerçevesi) dönüştürmek için. Daha sonra, sonuçların şu şekilde saklandığı varsayılarak df:

df.to_csv()

Hangi bir dize döndürebilir veya doğrudan bir csv dosyasına yazabilirsiniz.

Önceki cevapların ayrıntılarına dayanarak, kısayol için pandalara teşekkür etmeliyiz.


1
Bu harika bir cevap (+1) - çok basit ve .to_csv()gerçekten güçlü (örneğin, ücretsiz sütun filtreleme). Pandaları öğrenmem gerekiyor.
WoJ

3
Belirtildiği gibi, bu cevap bu sorudaki veriler için işe yaramaz. orient='records'ayarlanmalıdır, ancak her satır fieldsyine bir dictOP olacaktır , bu OP'nin istediği değildir.
Trenton McKinney

90

JSON dosyanızın sözlüklerin bir listesi halinde çözüleceğini varsayıyorum. Öncelikle JSON nesnelerini düzleştirecek bir işleve ihtiyacımız var:

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

Bu snippet'i JSON nesnenizde çalıştırmanın sonucu:

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

dır-dir

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

Bu işlevi JSON nesnelerinin giriş dizisindeki her diktüye uyguladıktan sonra:

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

ve ilgili sütun adlarını bulma:

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

bunu csv modülü üzerinden çalıştırmak zor değil:

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

Umarım bu yardımcı olur!


Python 3.6 kullanarak, son döngü çalışması için düzleştirilmiş JSON listesini yapmak zorunda kaldı: "input = list (map (lambda x: flattenjson (x," __ "), input))". Yine de yinelenebilir neden yeterli olmadığını anlamıyorum. Ayrıca verilerim UTF8 kullandığından çıkış dosyasını açarken kodlamayı belirtmek zorunda kaldım. Kesinlikle yardımcı oldu, teşekkür ederim !!
Alexis R

Bu harika, teşekkürler Alec! Birden çok yuvalama seviyesiyle çalışmak için değiştirdim: stackoverflow.com/a/57228641/473201
phreakhead

35

JSON çok çeşitli veri yapılarını temsil edebilir - JS "nesnesi" kabaca bir Python dict (dize anahtarları ile), kabaca bir Python listesi gibi bir JS "dizisi" gibidir ve bunları son " yaprak "elemanları sayı veya dizgidir.

CSV temel olarak yalnızca 2 boyutlu bir tabloyu temsil edebilir - isteğe bağlı olarak ilk satır "başlıklar", yani "sütun adları" ile, tablonun normal yorumlama yerine bir dikte listesi olarak yorumlanmasını sağlayabilir. listeler (yine, "yaprak" öğeleri sayılar veya dizeler olabilir).

Bu nedenle, genel durumda, keyfi bir JSON yapısını CSV'ye çeviremezsiniz. Birkaç özel durumda (başka yuvalama olmayan diziler; tamamen aynı tuşlara sahip nesnelerin dizileri) yapabilirsiniz. Sorununuz için varsa, hangi özel durum geçerlidir? Çözümün ayrıntıları, hangi özel duruma sahip olduğunuza bağlıdır. Hangisinin geçerli olduğunu bile belirtmediğiniz şaşırtıcı gerçeği göz önünde bulundurursak, kısıtlamayı dikkate almamış olabileceğinizden şüpheleniyorum, aslında her iki kullanılabilir durum da geçerlidir ve sorununuzu çözmek imkansızdır. Ama lütfen açıklığa kavuşturun!


31

Herhangi bir json düz nesne listesini csv'ye çeviren genel bir çözüm .

İnput.json dosyasını komut satırında ilk bağımsız değişken olarak iletin.

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
Önemli bir yorum - bu kod sütunları / başlıkları ilk satırdaki alanlardan alır. Json verilerinizde 'pürüzlü' sütunlar varsa, yani diyelim ki satır1'in 5 sütunu vardır, ancak satır2'nin 6 sütunu varsa, tüm sütunların toplam kümesini almak ve bunu üstbilgi olarak kullanmak için verilerin üzerinden bir ilk geçiş yapmanız gerekir.
Mike Repass

Sahip olduğum verilerle, ihtiyacım olan çözümün büyük bir parçasıydı, çünkü JSON'um pürüzlü değildi, bunu mevcut bir komut dosyasında çalıştırdığım için çıktı için bazı küçük ayarlarla harika çalıştı.
MichaelF

1
Bu kod ayrıca değerlerin başlık satırındaki anahtarlarla aynı sırada çıkacağını varsayar. Bu şansla işe yaramış olsa da, hiçbir şekilde garanti edilmez.
RyanHennig

Kodlama hatası alınıyor. Utf-8'e kodlama nasıl eklenir?
Elad Tabak

25

JSON verilerinizin adlı bir dosyada olduğu varsayılarak, bu kod sizin için çalışmalıdır 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, hayır - csv_file.writerow( f.writerowelbette hayır , orada bir yazım hatası yaptığınızı varsayıyorum!) Bir diksiyon değil bir sekans istiyor - ve örneğinizde her öğe bir diksiyon. Cevabımda tanımladığım gibi bu, JSON dosyasının bir dizi diziye sahip olduğu diğer özel durum için işe yarar; bir dizi nesne için işe yaramaz, ki bu çözmeye çalıştığınız özel durumdur (bir tane gerektirir csv.DictWriter- ve elbette alan adlarını çıkarmanız ve somutlaştırmak için bir siparişe karar vermeniz gerekir. ! -).
Alex Martelli

@DanLoewenherz Bu, son Python sürümlerinde çalışmaz. TypeError: listeye yalnızca listeyi birleştirebilir ("dict_values" değil)
Apolo Radomer

18

Kullanımı kolay olacak csv.DictWriter(), ayrıntılı uygulama şöyle olabilir:

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

Bunun tüm JSON nesnelerinizin aynı alanlara sahip olduğunu varsaydığını unutmayın.

İşte size yardımcı olabilecek referans .


Bu bağlantı soruyu cevaplayabilse de, cevabın temel kısımlarını buraya eklemek ve bağlantıyı referans olarak sağlamak daha iyidir. Bağlantı verilen sayfa değişirse, yalnızca bağlantı yanıtları geçersiz olabilir. - Şu kaynaktan
Mathieu

3
@purplepsycho Bu yanıtı, yalnızca bağlantı için hak edilen bir aşağı oyla buldum. Sadece bağlantının iyi bir yanıt olmadığını bilmeyen yeni kullanıcı bunu düzeltti. Ben oy verdim; belki de yeni kullanıcıyı topluluğumuza katılmaya devam etmeye teşvik etmek için?
Mawg, Monica

6

Dan'ın önerdiği çözümle ilgili sorun yaşıyordum , ama bu benim için çalıştı:

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

"Test.json" aşağıdakileri içeriyorsa:

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

Programınızı örnek verilerinizde denemede hata aldınız. '], item [' model ']] + item [' fields ']. değerler ()) TypeError: listeye yalnızca listeyi birleştirebilir ("dict_values" değil)
Mian Asbat Ahmad

Şimdi Python 2.7.9'da tekrar denedim ve benim için iyi çalışıyor.
Amanda

6

Kullan json_normalizedan pandas:

  • Sağlanan veriler göz önüne alındığında, adlı bir dosyada test.json
  • encoding='utf-8' gerekli olmayabilir.
  • Aşağıdaki kod pathlibkütüphaneden yararlanır
    • .open bir yöntemdir pathlib
    • Windows olmayan yollarla da çalışır
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')

CSV Çıkışı:

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

Daha fazla iç içe JSON nesneleri için Diğer Kaynaklar:


4

Önceki yanıtlarda belirtildiği gibi, json'u csv'ye dönüştürmenin zorluğu, bir json dosyasının iç içe sözlükler içerebilmesi ve bu nedenle bir 2D veri yapısı olan bir csv'ye karşı çok boyutlu bir veri yapısı olabilmesidir. Bununla birlikte, çok boyutlu bir yapıyı bir csv'ye dönüştürmenin iyi bir yolu, birincil anahtarlarla birbirine bağlanan birden fazla csv'ye sahip olmaktır.

Örneğin, ilk csv çıktısında sütunlarınız olarak "pk", "model", "alanlar" sütunları bulunur. "Pk" ve "model" değerlerini elde etmek kolaydır, ancak "alanlar" sütunu bir sözlük içerdiğinden, kendi csv'si olmalıdır ve "kod adı" birincil anahtar olarak göründüğü için, giriş olarak kullanabilirsiniz "csv" için ilk csv. İkinci csv, 2 csv'yi birbirine bağlamak için kullanılabilecek birincil anahtar olarak kod adı olan "alanlar" sütunundan sözlüğü içerir.

İşte iç içe sözlükleri 2 csvs'e dönüştüren json dosyanız için bir çözüm.

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

Bu sorunun sorulmasından bu yana uzun zaman geçtiğini biliyorum ama başkalarının cevabını ekleyebileceğimi ve çözümü çok özlü bir şekilde açıkladığını düşündüğüm bir blog gönderisini paylaşabileceğimi düşündüm.

İşte bağlantı

Yazmak için bir dosya açın

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

Csv writer nesnesini oluşturma

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

İçeriği kaydetmek için dosyayı kapattığınızdan emin olun

employ_data.close()

3

Bunu yapmanın çok akıllıca bir yolu değil, ama aynı problemi yaşadım ve bu benim için çalıştı:

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

Alec'in cevabı harika, ancak birden çok yuvalama seviyesinin olduğu durumda işe yaramıyor. İşte birden çok iç içe yerleştirme düzeyini destekleyen değiştirilmiş bir sürüm. Ayrıca, iç içe geçmiş nesne zaten kendi anahtarını belirtiyorsa başlık adlarını biraz daha güzel hale getirir (örn. Firebase Analytics / BigTable / BigQuery verileri):

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

Bu nispeten iyi çalışıyor. Bir csv dosyasına yazmak için json'u düzleştirir. İç içe öğeler yönetilir :)

Bu python 3 için

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)

zevk almak.


.csv dosyası oluşturulmaz, bunun yerine csv metni konsola çıktı olarak verilir. Ayrıca, json.loadsçalışma değildi, ben json.loadbir liste nesnesi verir güzel , ile çalıştım . Üçüncüsü, yuvalanmış elemanlar kayboldu.
ZygD

2

Bunu çözmenin basit yolu:

Şunun gibi yeni bir Python dosyası oluşturun: json_to_csv.py

Bu kodu ekleyin:

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

Bu kodu ekledikten sonra dosyayı kaydedin ve terminalde çalıştırın:

python json_to_csv.py input.txt output.csv

Umarım bu sana yardımcı olur.

GÖRÜŞÜRÜZ!


1
Bu örnek bir cazibe gibi çalışıyor! paylaşım için teşekkürler ben bu python komut dosyasını kullanarak json dosyamı CSV dönüştürmek başardı
Mostafa

2

Şaşırtıcı bir şekilde, buraya gönderilen cevapların hiçbirinin tüm olası senaryolarla (örneğin, iç içe dikler, iç içe listeler, Hiçbir değer, vb.)

Bu çözüm tüm senaryolarda çalışmalıdır:

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

Bunu dene

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

Bu kod herhangi bir json dosyası için çalışır

# -*- 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

Alec McGail'in içindeki listelerle JSON'u destekleme cevabı değiştirildi

    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

Teşekkürler!


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

Json format dosyasını csv formatlı dosyaya dönüştürmek için aşağıdaki örneği ele alırsak.

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

Aşağıdaki kod, json dosyasını (data3.json) csv dosyasına (data3.csv) dönüştürecektir.

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

Yukarıda belirtilen kod, yerel olarak yüklenen pycharm'da yürütüldü ve json dosyasını csv dosyasına başarıyla dönüştürdü. Umarım bu dosyaları dönüştürmek için yardımcı olur.


0

Veriler sözlük biçiminde göründüğü için, satırları gerçekten uygun başlık bilgileriyle çıktılamak için gerçekten csv.DictWriter () kullanmanız gerekir. Bu, dönüştürmenin biraz daha kolay yapılmasına izin vermelidir. Daha sonra fieldnames parametresi, ilk satırın çıktılar olarak çıktısı, daha sonra csv.DictReader () tarafından okunmasına ve işlenmesine izin verirken siparişi düzgün bir şekilde ayarlayacaktır.

Örneğin, Mike Repass

output = csv.writer(sys.stdout)

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

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

Ancak ilk kurulumu yalnızca output = csv.DictWriter olarak değiştirin (dosya ayarı, fieldnames = data [0] .keys ())

Bir sözlükteki öğelerin sırası tanımlanmadığından, alan adları girişlerini açıkça oluşturmanız gerekebileceğini unutmayın. Bunu yaptıktan sonra, yazma makinesi çalışacaktır. Yazmalar daha sonra gösterildiği gibi çalışır.


0

Ne yazık ki şaşırtıcı @Alec McGail cevabına küçük bir katkı yapmak için enouthg itibarım yok. Python3 kullanıyordum ve haritayı @Alexis R yorumunu izleyerek bir listeye dönüştürmem gerekiyordu.

Ayrıca csv yazar dosyaya ekstra bir CR ekledi bulduk (csv dosyası içindeki veriler ile her satır için boş bir satır var). @Jason R. Coombs'un bu konuya verdiği cevabı takiben çözüm çok kolaydı: Python'daki CSV, ekstra bir satır başı ekledi

Csv.writer öğesine lineterminator = '\ n' parametresini eklemeniz yeterlidir. Olacak:csv_w = csv.writer( out_file, lineterminator='\n' )


0

Bir json dosyasını csv dosyasına dönüştürmek için bu kodu kullanabilirsiniz Dosyayı okuduktan sonra, nesneyi panda veri çerçevesine dönüştürüyorum ve sonra bunu bir CSV dosyasına kaydediyorum

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)

bu, alt alanları (örnekteki "alanlar" gibi) dikkate almaz - alt nesne, içerikleri ayrı ayrı sütunlara ayrılmak yerine bir sütundadır.
Cribber

0

Partiye geç kalabilirim, ama sanırım, benzer sorunla başa çıktım. Böyle bir json dosyası vardı

JSON Dosya Yapısı

Sadece bu json dosyasından birkaç anahtar / değer ayıklamak istedim. Yani, aynı kodu çıkarmak için aşağıdaki kodu yazdım.

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

Umarım bu yardımcı olacak. Bu kod çalışması kontrol edebilirsiniz ilgili ayrıntılı bilgi için buraya


0

Bu @ MikeRepass'ın cevabının bir modifikasyonudur. Bu sürüm CSV'yi bir dosyaya yazar ve hem Python 2 hem de Python 3 için çalışır.

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())
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.