मैं JSON को CSV में कैसे बदल सकता हूं?


184

मेरे पास एक JSON फाइल है जिसे मैं एक CSV फाइल में बदलना चाहता हूं। मैं पायथन के साथ यह कैसे कर सकता हूं?

मैंने कोशिश की:

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

हालांकि, यह काम नहीं किया। मैं 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:
    f.writerow(item)  # ← changed

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
        }
    }
]

1
csv_file.writerow (आइटम) को आइटम को स्ट्रिंग्स या संख्याओं की एक सरल सूची की आवश्यकता होती है। प्रत्येक जसन ऑब्जेक्ट को एक फ्लैट सूची में बदलने की कोशिश करें, जैसे {"pk": 22, "मॉडल": "dif.permission"} बन जाएगा [22, dif.permission]।
सप्प्रेसफायर

1
jqजैसा कि यहाँ बताया गया है, इसका एक सरल तरीका है: stackoverflow.com/questions/32960857/…
मीका इलियट

तीसरा पक्ष विकल्प: json-csv.com (एकबारगी रूपांतरण के लिए) या json-csv.com/api को पायथन के साथ स्वचालित करने के लिए। यह अधिक जटिल JSON संरचनाओं के लिए एक सरल समाधान है।
स्टैक मैन

जवाबों:


129

सबसे पहले, आपके 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

2
यह काम है, लेकिन इससे पहले कि मैं कुछ पाने के लिए खेद है कि मुश्किल कोड मैं बात नहीं यह बेहतर आईडी मैं f.writerow (a) और a का उपयोग कर सकता है कुछ है जो मैं धन्यवाद से पहले घोषित
थोड़ा_फिशर

मेरे लिए यह लगभग पूरी तरह से काम करता है। निर्यात किए गए CSV में, कुछ खेतों से घिरा हुआ है [u'और ']। (गैर-पोस्ट-प्रोसेसिंग) वर्कअराउंड क्या है? अगर वहाँ एक है ... :)
Dror

3
नीचे मैंने इसे अधिक-आम तौर पर करने का एक तरीका दिखाया है, बिना हार्ड-कोड के
एस्क मैकगैल

4
हे, मैं यह कोशिश की है, लेकिन मैं एक TypeError: a bytes-like object is required, not 'str'हो रहा हूँf.writerow(['pk', 'model', 'codename', 'name', 'content_type'])
आदित्य हरिहरन

8
python3 के लिए csv फ़ाइल खोलने के साथ लाइन बदलेंf = csv.writer(open("test.csv", "w", newline=''))
PiotrK

119

pandas पुस्तकालय के साथ , यह दो कमांड का उपयोग करने के रूप में आसान है!

pandas.read_json()

JSON स्ट्रिंग को पंडों ऑब्जेक्ट (या तो एक श्रृंखला या डेटाफ़्रेम) में परिवर्तित करने के लिए। फिर, यह मानते हुए कि परिणामों को संग्रहीत किया गया था df:

df.to_csv()

जो या तो एक स्ट्रिंग लौटा सकता है या सीधे एक सीएसवी-फाइल पर लिख सकता है।

पिछले उत्तरों की क्रियाशीलता के आधार पर, हम सभी को शॉर्टकट के लिए पांडा का धन्यवाद करना चाहिए।


1
यह एक शानदार उत्तर है (+1) - इतना सरल और .to_csv()वास्तव में शक्तिशाली है (उदाहरण के लिए मुफ्त में कॉलम फ़िल्टरिंग)। मुझे पंडों को सीखने की जरूरत है।
WoJ

3
जैसा कि बताया गया है, यह उत्तर इस प्रश्न में डेटा के लिए काम नहीं करता है। orient='records'सेट होना चाहिए, लेकिन प्रत्येक पंक्ति fieldsअभी भी एक होगी dict, जो ओपी ने अनुरोध नहीं किया है।
ट्रेंटन मैककिनी

90

मैं मान रहा हूं कि आपकी 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 ) )

सीएसवी मॉड्यूल के माध्यम से इसे चलाना मुश्किल नहीं है:

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

आशा है कि ये आपकी मदद करेगा!


पायथन 3.6 का उपयोग करते हुए, मुझे अंतिम लूप काम करने के लिए चपटा JSON की एक सूची बनानी थी: "इनपुट = सूची (नक्शा (लैम्ब्डा x: flattenjson (x," __ "), इनपुट))"। मुझे यह समझ में नहीं आता है कि हालांकि चलने योग्य पर्याप्त नहीं है। मुझे आउटपुट फ़ाइल खोलते समय एन्कोडिंग को भी निर्दिष्ट करना पड़ा क्योंकि मेरा डेटा UTF8 का उपयोग करता है। यह निश्चित रूप से मदद की, धन्यवाद !!
एलेक्सिस आर

यह बहुत अच्छा है, धन्यवाद एलेक! मैंने इसे नेस्टिंग के कई स्तरों के साथ काम करने के लिए संशोधित किया: stackoverflow.com/a/57228641/473201
फ़्रीहेड हेड

35

JSON डेटा संरचनाओं की एक विस्तृत विविधता का प्रतिनिधित्व कर सकता है - एक जेएस "ऑब्जेक्ट" लगभग पायथन की तरह तानाशाह (स्ट्रिंग कुंजी के साथ), एक जेएस "सरणी" है, जो लगभग पायथन सूची की तरह है, और आप उन्हें अंतिम रूप से लंबे समय तक घोंसला बना सकते हैं। पत्ती "तत्व संख्या या तार हैं।

CSV अनिवार्य रूप से केवल 2-डी तालिका का प्रतिनिधित्व कर सकता है - वैकल्पिक रूप से "हेडर" की पहली पंक्ति के साथ, अर्थात, "कॉलम नाम", जो सामान्य व्याख्या के बजाय तालिका की व्याख्या करने योग्य सूची के रूप में बना सकते हैं। सूचियां (फिर से, "पत्ती" तत्व संख्या या तार हो सकते हैं)।

इसलिए, सामान्य स्थिति में, आप एक CSV में JSON संरचना का मनमाना अनुवाद नहीं कर सकते। कुछ विशेष मामलों में आप कर सकते हैं (बिना आगे के घोंसले के साथ सरणियों का सरणी; वस्तुओं की सरणियाँ, जिनमें सभी बिल्कुल समान कुंजी हैं)। कौन सा विशेष मामला, यदि कोई हो, आपकी समस्या पर लागू होता है? समाधान का विवरण इस बात पर निर्भर करता है कि आपके पास कौन सा विशेष मामला है। आश्चर्यजनक तथ्य को देखते हुए कि आप यह भी उल्लेख नहीं करते हैं कि कौन सा लागू होता है, मुझे संदेह है कि आपने बाधा पर विचार नहीं किया होगा, न तो वास्तव में प्रयोग करने योग्य मामला लागू होता है, और आपकी समस्या को हल करना असंभव है। लेकिन कृपया स्पष्ट करें!


31

एक जेनेरिक समाधान जो फ्लैट वस्तुओं के किसी भी जोंस सूची को सीएसवी में अनुवाद करता है।

कमांड लाइन पर पहले तर्क के रूप में input.json फ़ाइल पास करें।

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
एक महत्वपूर्ण टिप्पणी - यह कोड पहली पंक्ति में कॉलम / हेडर को खेतों से हटाता है। यदि आपके json डेटा में 'jagged' कॉलम हैं, तो बता दें कि row1 में 5 कॉलम हैं, लेकिन row2 में 6 कॉलम हैं, तो आपको सभी कॉलम के कुल सेट को प्राप्त करने के लिए डेटा पर पहला पास करने की आवश्यकता है और हेडर के रूप में उपयोग करें।
माइक रिपैस

डेटा के साथ मेरे पास यह एक बहुत बड़ा हिस्सा था जो मुझे चाहिए था, क्योंकि मेरे JSON को दांतेदार नहीं किया गया था क्योंकि यह आउटपुट के लिए कुछ मामूली समायोजन के साथ आश्चर्यजनक रूप से काम करता था क्योंकि मैं इसे मौजूदा स्क्रिप्ट के भीतर चला रहा था।
माइकल एफएफ

1
यह कोड यह भी मानता है कि हेडर पंक्ति में कुंजियाँ उसी क्रम में आउटपुट होंगी। जबकि वह भाग्य से काम कर सकता है, यह कोई गारंटी नहीं है।
रयानहैनिग

एन्कोडिंग त्रुटि हो रही है। किसी भी विचार कैसे utf-8 में एन्कोडिंग जोड़ने के लिए?
इलाद तबक '

25

इस कोड को आपके लिए काम करना चाहिए, यह मानते हुए कि आपका 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:
        fields = list(item['fields'].values())
        csv_file.writerow([item['pk'], item['model']] + fields)

1
हम्म, नहीं - csv_file.writerow( f.writerowबिल्कुल नहीं है, मुझे लगता है कि आपने वहां एक टाइपो बना दिया है!) एक अनुक्रम चाहता है, एक तानाशाह नहीं - और आपके उदाहरण में, प्रत्येक आइटम एक तानाशाही है। यह अन्य विशेष मामले के लिए काम करेगा, जैसा कि मैंने अपने उत्तर में पहचाना है - जहां JSON फ़ाइल में ऐरे की एक सरणी है; यह वस्तुओं की एक सरणी के लिए काम नहीं करता है, जो विशेष मामला है जिसे आप हल करने की कोशिश करते हुए दिखाई देते हैं (यह कि आपको एक की आवश्यकता है csv.DictWriter- और निश्चित रूप से आपको फ़ील्ड नामों को निकालने की आवश्यकता है और इसे तुरंत करने के लिए एक आदेश पर निर्णय लेना होगा। -)।
एलेक्स मार्टेली 4

@DanLoewenherz हाल के पायथन संस्करणों पर काम नहीं करता है। TypeError: केवल सूची ("तानाशाह" नहीं) को सूची में
रख सकते हैं

18

इसका उपयोग करना आसान होगा csv.DictWriter(), विस्तृत कार्यान्वयन इस तरह हो सकता है:

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

ध्यान दें कि यह मानता है कि आपके JSON ऑब्जेक्ट्स के सभी फ़ील्ड समान हैं।

यहाँ संदर्भ है जो आपकी मदद कर सकता है।


हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को शामिल करना और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक-केवल उत्तर अमान्य हो सकते हैं यदि लिंक किए गए पृष्ठ बदल जाते हैं। - समीक्षा से
मैथ्यू 10

3
@purplepsycho मुझे यह उत्तर एक अपमानजनक के साथ मिला, जो केवल लिंक होने के योग्य था। नया उपयोगकर्ता, जो इस बात से अनजान हो सकता है कि लिंक केवल एक अच्छा उत्तर नहीं है, ने इसे ठीक कर दिया है। मैंने उत्थान किया; शायद आप भी, नए उपयोगकर्ता को हमारे समुदाय में भाग लेने के लिए प्रोत्साहित करने के लिए प्रोत्साहित कर सकते हैं?
मावग का कहना है कि मोनिका

6

मुझे डैन के प्रस्तावित समाधान से परेशानी हो रही थी , लेकिन इसने मेरे लिए काम किया:

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" में निम्नलिखित शामिल थे:

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

अपने नमूना डेटा C: \ curl> python json2csv.py Traceback (सबसे हालिया कॉल अंतिम): पंक्ति 11, लाइन 11 को <मॉड्यूल> f.writeow ([आइटम ['pk) में अपने प्रोग्राम को आज़माने में त्रुटि हुई। '], आइटम [' मॉडल ']] + आइटम [' फ़ील्ड्स]]। मान ()) टाइपर्र: केवल सूची के लिए सूची ("तानाशाही" नहीं) कर सकते हैं
मियां

अभी इसे फिर से पायथन 2.7.9 में लाया और यह मेरे लिए ठीक काम करता है।
अमांडा

6

का प्रयोग करें json_normalizeसे pandas:

  • दिए गए फ़ाइल में दिए गए डेटा को देखते हुए test.json
  • encoding='utf-8' आवश्यक नहीं हो सकता है।
  • निम्नलिखित कोड pathlibपुस्तकालय का लाभ उठाता है
    • .open की एक विधि है pathlib
    • गैर-विंडोज पथ के साथ भी काम करता है
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 आउटपुट:

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

अधिक भारी नेस्टेड JSON ऑब्जेक्ट्स के लिए अन्य संसाधन:


4

जैसा कि पिछले उत्तरों में उल्लेख किया गया है कि json को csv में बदलने में कठिनाई इसलिए है क्योंकि एक json फाइल में नेस्टेड डिक्शनरी हो सकती है और इसलिए एक बहुआयामी डेटा संरचना एक csv छंद है जो 2D डेटा संरचना है। हालाँकि, एक csv के लिए बहुआयामी संरचना को चालू करने का एक अच्छा तरीका कई csvs है जो प्राथमिक कुंजियों के साथ टाई करते हैं।

आपके उदाहरण में, पहले csv आउटपुट में आपके कॉलम के रूप में "pk", "मॉडल", "फ़ील्ड" हैं। "पीके", और "मॉडल" के लिए मान प्राप्त करना आसान है, लेकिन क्योंकि "फ़ील्ड" कॉलम में एक शब्दकोश है, यह अपना स्वयं का सीएसवी होना चाहिए और क्योंकि "कोडनेम" प्राथमिक कुंजी प्रतीत होता है, आप इनपुट के रूप में उपयोग कर सकते हैं पहला फ़ील्ड पूरा करने के लिए "फ़ील्ड" के लिए। दूसरी csv में कोडेन के साथ "फ़ील्ड्स" कॉलम में प्राथमिक कुंजी के रूप में शब्दकोष है, जिसका उपयोग 2 csvs को एक साथ टाई करने के लिए किया जा सकता है।

यहाँ आपकी json फाइल का समाधान है जो एक नेस्टेड डिक्शनरी को 2 csv में कनवर्ट करता है।

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

मुझे पता है कि इस प्रश्न को पूछे जाने में काफी समय हो गया है, लेकिन मैंने सोचा कि मैं हर किसी के उत्तर को जोड़ सकता हूं और एक ब्लॉग पोस्ट साझा कर सकता हूं जो मुझे लगता है कि समाधान को बहुत ही संक्षिप्त तरीके से समझाता हूं।

यहाँ लिंक है

लिखने के लिए एक फ़ाइल खोलें

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

सीएसवी लेखक ऑब्जेक्ट बनाएँ

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

3

यह करने के लिए एक बहुत ही स्मार्ट तरीका नहीं है, लेकिन मुझे एक ही समस्या है और यह मेरे लिए काम करता है:

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

एलेक का जवाब बहुत अच्छा है, लेकिन यह उस मामले में काम नहीं करता है जहां घोंसले के कई स्तर हैं। यहां एक संशोधित संस्करण है जो कई स्तरों के घोंसले के शिकार का समर्थन करता है। यह हेडर के नाम को भी अच्छा बनाता है यदि नेस्टेड ऑब्जेक्ट पहले से ही अपनी कुंजी निर्दिष्ट करता है (जैसे फायरबेस एनालिटिक्स / बिगटेबल / बिगविक डेटा):

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

यह अपेक्षाकृत अच्छी तरह से काम करता है। यह एक csv फ़ाइल में लिखने के लिए json को समतल करता है। नेस्टेड तत्वों का प्रबंधन किया जाता है :)

वह अजगर 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)

का आनंद लें।


.csv फ़ाइल जेनरेट नहीं हुई थी, इसके बजाय, csv टेक्स्ट कंसोल में आउटपुट था। इसके अलावा, json.loadsकाम नहीं कर रहा था, मैंने इसके साथ काम किया json.load, जो अच्छी तरह से एक सूची ऑब्जेक्ट को जन्म देता है। तीसरा, नेस्टेड तत्व खो गए थे।
ZygD

2

इसे हल करने का मेरा सरल तरीका:

एक नया पायथन फ़ाइल बनाएं जैसे: 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

उम्मीद है इससे आपको मदद होगी।

फिर मिलेंगे!


1
यह नमूना एक आकर्षण की तरह काम करता है! साझा करने के लिए धन्यवाद, मैं इस अजगर स्क्रिप्ट का उपयोग करके अपने json फ़ाइल को CSV में परिवर्तित करने में सक्षम था
Mostafa

2

हैरानी की बात है, मैंने पाया कि अब तक यहां पोस्ट किए गए उत्तरों में से कोई भी सभी संभावित परिदृश्यों (जैसे, नेस्टेड डीकट्स, नेस्टेड लिस्ट, कोई भी मूल्य, आदि) से सही ढंग से नहीं निपटता है।

यह समाधान सभी परिदृश्यों पर काम करना चाहिए:

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

इसे इस्तेमाल करे

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

यह कोड किसी भी दिए गए json फ़ाइल के लिए काम करता है

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

जेन्स को अंदर की सूचियों के साथ समर्थन करने के लिए संशोधित एलेक मैकगेल का उत्तर

    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

धन्यवाद!


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 स्वरूप फ़ाइल को csv स्वरूपित फ़ाइल में परिवर्तित करने के लिए नीचे दिए गए उदाहरण पर विचार करें।

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

नीचे दिया गया कोड json फाइल (data3.json) को 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')])

उपर्युक्त कोड स्थानीय रूप से स्थापित pycharm में निष्पादित किया गया है और इसने सफलतापूर्वक json फाइल को csv फाइल में बदल दिया है। उम्मीद है कि यह फ़ाइलों को परिवर्तित करने में मदद करेगा।


0

चूंकि डेटा एक शब्दकोश प्रारूप में प्रतीत होता है, ऐसा प्रतीत होता है कि आपको वास्तव में उचित हेडर जानकारी के साथ लाइनों का उत्पादन करने के लिए सीएसवीडक्टविटर () का उपयोग करना चाहिए। इससे रूपांतरण को कुछ हद तक आसान किया जा सकता है। फ़ील्डनाम पैरामीटर तब आदेश को ठीक से सेट करेगा जबकि पहली पंक्ति का आउटपुट हेडर के रूप में इसे पढ़ने और बाद में csv.DictReader () द्वारा संसाधित करने की अनुमति देगा।

उदाहरण के लिए, माइक रिपास का इस्तेमाल किया

output = csv.writer(sys.stdout)

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

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

हालाँकि, प्रारंभिक सेटअप को आउटपुट = csv.DictWriter (फाइलसेटिंग, फ़ील्डनाम = डेटा [0] .keys ()) में बदलें।

ध्यान दें कि चूंकि किसी शब्दकोश में तत्वों का क्रम परिभाषित नहीं है, इसलिए आपको स्पष्ट रूप से फ़ील्ड नाम प्रविष्टियाँ बनानी पड़ सकती हैं। एक बार जब आप ऐसा करेंगे, तो लेखक काम करेगा। लेखन तब मूल रूप से काम करता है।


0

दुर्भाग्य से मैंने अद्भुत @Alec McGail उत्तर में एक छोटा सा योगदान करने के लिए प्रतिष्ठा नहीं ली है। मैं Python3 का उपयोग कर रहा था और मुझे @Alexis R टिप्पणी के बाद नक्शे को सूची में बदलने की आवश्यकता है।

अतिरिक्त मैंने पाया है कि सीएसवी लेखक फ़ाइल में एक अतिरिक्त सीआर जोड़ रहा है (मेरे पास सीएसवी फ़ाइल के अंदर डेटा के साथ प्रत्येक पंक्ति के लिए एक खाली लाइन है)। इस धागे के जवाब में @Jason R. Coombs के जवाब के बाद समाधान बहुत आसान था: पायथन में CSV ने अतिरिक्त कार सेवा वापसी को जोड़ा

आपको बस cseterminator = '\ n' पैरामीटर को csv.writer में जोड़ना होगा। यह:csv_w = csv.writer( out_file, lineterminator='\n' )


0

आप इस कोड का उपयोग किसी json फाइल को csv फ़ाइल में बदलने के लिए कर सकते हैं। फ़ाइल को पढ़ने के बाद, मैं ऑब्जेक्ट को पांडा डेटाफ़्रेम में परिवर्तित कर रहा हूं और फिर इसे 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)

यह सबफ़ोल्ड्स (जैसे "फ़ील्ड्स" उदाहरण में ") को ध्यान में नहीं रखता है - उप-ऑब्जेक्ट एक कॉलम में अलग-अलग कॉलम के साथ-साथ इसकी सामग्री के बजाय होता है।
क्राइबर

0

मुझे पार्टी के लिए देर हो सकती है, लेकिन मुझे लगता है, मैंने इसी तरह की समस्या से निपटा है। मेरे पास एक json फ़ाइल थी जो इस तरह दिखती थी

JSON फ़ाइल संरचना

मैं केवल इन json फ़ाइल से कुछ कुंजी / मान निकालना चाहता था। तो, मैंने उसी को निकालने के लिए निम्न कोड लिखा।

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

मुझे उम्मीद है कि इससे सहायता मिलेगी। यह कोड कैसे काम करता है, इसकी जानकारी के लिए आप यहां देख सकते हैं


0

यह @ माइक रिपास के उत्तर का एक संशोधन है। यह संस्करण CSV को एक फ़ाइल में लिखता है, और पायथन 2 और पायथन 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())
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.