CSV फ़ाइल को बहु JSON में कैसे बदलें?


98

यहाँ मेरा कोड है, वास्तव में सरल सामान ...

import csv
import json

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

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

कुछ फ़ील्ड नामों की घोषणा करें, पाठक फ़ाइल को पढ़ने के लिए CSV का उपयोग करता है, और फ़ाइल को JSON प्रारूप में डंप करने के लिए दर्ज किए गए नाम। यहाँ समस्या है ...

CSV फ़ाइल में प्रत्येक रिकॉर्ड एक अलग पंक्ति पर है। मैं चाहता हूं कि JSON आउटपुट भी उसी तरह हो। समस्या यह है कि यह सब एक विशाल, लंबी लाइन पर है।

मैंने ऐसा कुछ उपयोग करने की कोशिश की है for line in csvfile:और फिर नीचे अपना कोड चला रहा हूं, reader = csv.DictReader( line, fieldnames)जिसके साथ प्रत्येक पंक्ति के माध्यम से लूप होता है, लेकिन यह पूरी फाइल को एक लाइन पर करता है, फिर दूसरी लाइन पर पूरी फाइल के माध्यम से लूप करता है ... तब तक जारी रहता है जब तक यह लाइनों से बाहर नहीं निकल जाता है ।

इसे सही करने के लिए कोई सुझाव?

संपादित करें: स्पष्ट करने के लिए, वर्तमान में मेरे पास है: (पंक्ति 1 पर प्रत्येक रिकॉर्ड)

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

मैं क्या देख रहा हूँ: (2 लाइनों पर 2 रिकॉर्ड)

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

प्रत्येक व्यक्ति अलग-अलग लाइन पर / इंडेंट नहीं करता है, लेकिन यह प्रत्येक रिकॉर्ड खुद की लाइन है।

कुछ सैंपल इनपुट।

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

मुझे यकीन नहीं है कि आपका कोड वही कहता है जो आप कहते हैं; यह उत्पादन [{..row..},{..row..},...]नहीं करना चाहिए {..row..}{..row..}..। कहने का मतलब यह है कि आउटपुट ऐसा लगता है कि यह जोंस ऑब्जेक्ट्स का एक जस्सन सरणी होगा, न कि अनकॉन्स्ड जोंस ऑब्जेक्ट्स की एक स्ट्रीम।
सिंगलएनजेशन इलिमिनेशन

जवाबों:


143

आपके वांछित आउटपुट के साथ समस्या यह है कि यह वैध डॉक्यूमेंट नहीं है; यह json दस्तावेजों की एक धारा है !

यह ठीक है, अगर इसकी आपको आवश्यकता है, लेकिन इसका मतलब है कि प्रत्येक दस्तावेज़ को आप अपने आउटपुट में चाहते हैं, तो आपको कॉल करना होगा json.dumps

चूंकि आप अपने दस्तावेज़ों को अलग करना चाहते हैं, इसलिए नई दस्तावेज़ उन दस्तावेज़ों में समाहित नहीं है, आप इसे स्वयं आपूर्ति करने के लिए हुक पर हैं। इसलिए हमें बस कॉल से लूप को json.dump पर खींचने की जरूरत है और लिखे गए प्रत्येक दस्तावेज़ के लिए नई सुचनाओं को इंटरस्ट करना होगा।

import csv
import json

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

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

1
उत्तम! क्षमा करें आपको इसे प्राप्त करने के लिए पढ़ने का थोड़ा मन करना पड़ा, और सुधार / स्पष्टीकरण के लिए धन्यवाद। यही वह है जिसकी तलाश में मैं हूं।
बीनबैगिंग

4
लेकिन समस्या यह है कि
पहनावा

1
@MONTYHS: इस उत्तर की पहली भावना बताती है कि आउटफिट कोई डॉक्यूमेंट नहीं है; और इसके बदले क्या है। क्या आपको उस व्यक्ति से अलग समस्या है जिसने यह प्रश्न पूछा है?
सिंगलएनजेशन इलिमिनेशन

6
@ abhi1610: यदि आप इनपुट में हेडर की उम्मीद कर रहे हैं, तो आपको तर्क DictReaderदिए बिना निर्माण करना चाहिए fieldnames; यह फ़ाइल से फ़ील्डनाम प्राप्त करने के लिए पहली पंक्ति पढ़ेगा।
सिंगलनेग्मेंटेशन ऑलिमिनेशन

1
और आपकी फ़ाइलों के लिए एन्कोडिंग जोड़ना अच्छा है csvfile = open('file.csv', 'r',encoding='utf-8') और jsonfile = open('file.json', 'w',encoding='utf-8')
मारेक बर्नड

21

आप इसे प्राप्त करने के लिए पंडों डेटाफ़्रेम का उपयोग कर सकते हैं, निम्न उदाहरण के साथ:

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

10

मैंने @ SingleNegationElimination की प्रतिक्रिया ली और इसे तीन-लाइनर में सरल किया, जिसका उपयोग पाइप लाइन में किया जा सकता है:

import csv
import json
import sys

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

8
import csv
import json

file = 'csv_file_name.csv'
json_file = 'output_file_name.json'

#Read CSV File
def read_CSV(file, json_file):
    csv_rows = []
    with open(file) as csvfile:
        reader = csv.DictReader(csvfile)
        field = reader.fieldnames
        for row in reader:
            csv_rows.extend([{field[i]:row[field[i]] for i in range(len(field))}])
        convert_write_json(csv_rows, json_file)

#Convert csv data into json
def convert_write_json(data, json_file):
    with open(json_file, "w") as f:
        f.write(json.dumps(data, sort_keys=False, indent=4, separators=(',', ': '))) #for pretty
        f.write(json.dumps(data))


read_CSV(file,json_file)

Json.dumps () का प्रलेखन


6

आप कोशिश कर सकते हैं इस

import csvmapper

# how does the object look
mapper = csvmapper.DictMapper([ 
  [ 
     { 'name' : 'FirstName'},
     { 'name' : 'LastName' },
     { 'name' : 'IDNumber', 'type':'int' },
     { 'name' : 'Messages' }
  ]
 ])

# parser instance
parser = csvmapper.CSVParser('sample.csv', mapper)
# conversion service
converter = csvmapper.JSONConverter(parser)

print converter.doConvert(pretty=True)

संपादित करें:

सरल दृष्टिकोण

import csvmapper

fields = ('FirstName', 'LastName', 'IDNumber', 'Messages')
parser = CSVParser('sample.csv', csvmapper.FieldMapper(fields))

converter = csvmapper.JSONConverter(parser)

print converter.doConvert(pretty=True)

3
मुझे लगता है कि आपके पास कम से कम, स्पष्ट रूप से उल्लेख होना चाहिए कि आप एक थर्ड-पार्टी मॉड्यूल का उपयोग कर रहे हैं csvmapper, ऐसा करने के लिए (और शायद जहां इसे प्राप्त करना है) कुछ अंतर्निर्मित के विपरीत।
मार्टीन्यू

2

indentकरने के लिए पैरामीटर जोड़ेंjson.dumps

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

यह भी ध्यान दें, आप बस json.dumpखुले के साथ उपयोग कर सकते हैं jsonfile:

json.dump(data, jsonfile)

काफी नहीं मैं क्या देख रहा हूँ। मैंने वांछित आउटपुट को स्पष्ट करने और दिखाने के लिए अपने मूल प्रश्न को संपादित किया। हालांकि टिप के लिए धन्यवाद, यह बाद में काम आ सकता है।
बीनबागकिंग

2

मैं देख रहा हूं कि यह पुराना है, लेकिन मुझे सिंगलनेशन इलिमिनेशन से कोड की आवश्यकता थी, हालांकि मेरे पास नॉन यूटीएफ -8 अक्षरों वाले डेटा के साथ समस्या थी। ये उन क्षेत्रों में दिखाई दिए जिनसे मैं अत्यधिक चिंतित नहीं था इसलिए मैंने उन्हें अनदेखा करने का विकल्प चुना। हालाँकि इसने कुछ प्रयास किए। मैं अजगर के लिए नया हूँ इसलिए कुछ परीक्षण और त्रुटि के साथ मुझे यह काम करने के लिए मिला। यूटीएफ -8 की अतिरिक्त हैंडलिंग के साथ कोड सिंगलनेगलाइजेशन क्लीयरेंस की एक प्रति है। मैंने इसे https://docs.python.org/2.7/library/csv.html के साथ करने की कोशिश की, लेकिन अंत में हार मान ली। नीचे दिए गए कोड ने काम किया।

import csv, json

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

fieldnames = ("Scope","Comment","OOS Code","In RMF","Code","Status","Name","Sub Code","CAT","LOB","Description","Owner","Manager","Platform Owner")
reader = csv.DictReader(csvfile , fieldnames)

code = ''
for row in reader:
    try:
        print('+' + row['Code'])
        for key in row:
            row[key] = row[key].decode('utf-8', 'ignore').encode('utf-8')      
        json.dump(row, jsonfile)
        jsonfile.write('\n')
    except:
        print('-' + row['Code'])
        raise

1

कैसे पांडवों का उपयोग करने के बारे में एक DataFrame ( pd.read_csv ) में सीएसवी फ़ाइल को पढ़ने के लिए , फिर कॉलम को हेरफेर करना यदि आप चाहते हैं (उन्हें छोड़ने या मूल्यों को अपडेट करना) और अंत में DataFrame को JSON ( pd.DataFrame.to_json ) में परिवर्तित करना ।

नोट: मैंने जाँच नहीं की है कि यह कितना कुशल होगा लेकिन यह निश्चित रूप से एक बड़े सीएसवी को जोड़-तोड़ करने और बदलने के लिए सबसे आसान तरीका है।


0

@MONTYHS जवाब में मामूली सुधार के रूप में, क्षेत्र के नामों के माध्यम से पुनरावृति:

import csv
import json

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

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

output = []

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

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

-1
import csv
import json
csvfile = csv.DictReader('filename.csv', 'r'))
output =[]
for each in csvfile:
    row ={}
    row['FirstName'] = each['FirstName']
    row['LastName']  = each['LastName']
    row['IDNumber']  = each ['IDNumber']
    row['Message']   = each['Message']
    output.append(row)
json.dump(output,open('filename.json','w'),indent=4,sort_keys=False)

जब मैं इसका उपयोग करने की कोशिश करता हूं तो मुझे "कीरोर: 'फर्स्टनाम' मिलता है। ऐसा लगता नहीं है कि कुंजी को जोड़ा जा रहा है। मुझे यकीन नहीं है कि आप यहां क्या करने की कोशिश कर रहे हैं, लेकिन मुझे नहीं लगता कि आउटपुट से मेल खाता है क्योंकि मैं उसी इंडेंट = 4 को वेन के रूप में उपयोग कर रहा हूं। मुझे क्या आउटपुट की उम्मीद करनी चाहिए? मैंने अपनी मूल पोस्ट को स्पष्ट करने के लिए संपादित किया कि मैं क्या देख रहा हूँ।
बीनबागकिंग

मुख्य त्रुटि सबसे अधिक संभावना है क्योंकि यह कोड हेडर तर्क पास नहीं करता है DictReader, इसलिए यह इनपुट फ़ाइल की पहली पंक्ति से फ़ील्ड के नाम का अनुमान लगा रहा है: जॉन, डो, 5, "फर्स्टनेम, लास्टनाम" के बजाय "कोई नहीं"। इतने पर ...
एकलकरण

बेहतर विकल्प, यह वास्तव में वांछित क्षेत्रों के लिए सीएसवी को पार्स करता है (केवल क्रम में नहीं, जैसा कि चिह्नित उत्तर में है)
गार्सियाडेलकैस्टिलो

मुझे एक त्रुटि कहते हुए कहा गया हैTypeError: expected string or buffer
CodyBugstein
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.