2012-11-20 5 views
5

का उपयोग कर सीएसवी को mongoimport- अनुकूल JSON में कनवर्ट करें मेरे पास 300 एमबी सीएसवी है जिसमें Geonames.org से 3 मिलियन पंक्तियों की शहर की जानकारी है। मैं mongoimport के साथ MongoDB में आयात करने के लिए इस सीएसवी को जेएसओएन में बदलने की कोशिश कर रहा हूं। जिस कारण से मैं JSON चाहता हूं वह यह है कि यह मुझे "लोक" फ़ील्ड को सरणी के रूप में निर्दिष्ट करने की अनुमति देता है और geospatial अनुक्रमणिका के साथ उपयोग के लिए एक स्ट्रिंग नहीं है। सीएसवी यूटीएफ -8 में एन्कोड किया गया है।पाइथन

"geonameid","name","asciiname","alternatenames","loc","feature_class","feature_code","country_code","cc2","admin1_code","admin2_code","admin3_code","admin4_code" 
3,"Zamīn Sūkhteh","Zamin Sukhteh","Zamin Sukhteh,Zamīn Sūkhteh","[48.91667,32.48333]","P","PPL","IR",,"15",,, 
5,"Yekāhī","Yekahi","Yekahi,Yekāhī","[48.9,32.5]","P","PPL","IR",,"15",,, 
7,"Tarvīḩ ‘Adāī","Tarvih `Adai","Tarvih `Adai,Tarvīḩ ‘Adāī","[48.2,32.1]","P","PPL","IR",,"15",,, 

वांछित JSON निर्गम (चारसेट को छोड़कर) कि mongoimport साथ काम करता है नीचे है::

{"geonameid":3,"name":"Zamin Sukhteh","asciiname":"Zamin Sukhteh","alternatenames":"Zamin Sukhteh,Zamin Sukhteh","loc":[48.91667,32.48333] ,"feature_class":"P","feature_code":"PPL","country_code":"IR","cc2":null,"admin1_code":15,"admin2_code":null,"admin3_code":null,"admin4_code":null} 
{"geonameid":5,"name":"Yekahi","asciiname":"Yekahi","alternatenames":"Yekahi,Yekahi","loc":[48.9,32.5] ,"feature_class":"P","feature_code":"PPL","country_code":"IR","cc2":null,"admin1_code":15,"admin2_code":null,"admin3_code":null,"admin4_code":null} 
{"geonameid":7,"name":"Tarvi? ‘Adai","asciiname":"Tarvih `Adai","alternatenames":"Tarvih `Adai,Tarvi? ‘Adai","loc":[48.2,32.1] ,"feature_class":"P","feature_code":"PPL","country_code":"IR","cc2":null,"admin1_code":15,"admin2_code":null,"admin3_code":null,"admin4_code":null} 

मैं सभी उपलब्ध ऑनलाइन सीएसवी की कोशिश की है

मेरी सीएसवी का एक स्निपेट इस तरह दिखता है -जॉन कनवर्टर्स और वे फ़ाइल आकार के कारण काम नहीं करते हैं। मुझे सबसे नज़दीकी मिला Mr Data Converter (उपरोक्त चित्रित) के साथ था जो दस्तावेज़ों के बीच प्रारंभ और अंत ब्रैकेट और कॉमा को हटाने के बाद मोंगो डीबी में आयात करेगा। दुर्भाग्यवश यह उपकरण 300 एमबी फ़ाइल के साथ काम नहीं करता है।

उपरोक्त JSON यूटीएफ -8 में एन्कोड किया गया है लेकिन अभी भी एक त्रुटि त्रुटि के कारण वर्णमाला की समस्याएं हैं?

मैंने पिछले तीन दिनों में पाइथन सीखने का प्रयास किया, पाइथन सीएसवीकेआईटी का उपयोग करने की कोशिश की, स्टैक ओवरफ्लो पर सभी सीएसवी-जेएसओएन स्क्रिप्ट का प्रयास किया, मोंगोडीबी को सीएसवी आयात किया और सरणी में "लोक" स्ट्रिंग को बदल दिया (यह दुर्भाग्यवश उद्धरण चिह्नों को बरकरार रखता है) और एक समय में 30,000 रिकॉर्ड मैन्युअल रूप से कॉपी और पेस्ट करने का भी प्रयास कर रहे हैं। बहुत सारे रिवर्स इंजीनियरिंग, परीक्षण और त्रुटि और बहुत आगे।

क्या किसी के पास सीएसवी में उचित एन्कोडिंग को उचित रखते हुए उपरोक्त JSON को प्राप्त करने का संकेत है? मैं पूरी तरह से स्थिर हूं।

+0

संभावित डुप्लिकेट का उपयोग कर सीएसवी MongoDB में सीधे आयात करने की कोशिश कर सकते: http://stackoverflow.com/questions/1884395/csv-to-json-script – xiaoyi

+0

मेरा प्रश्न के संबंध में है स्वरूपण और त्रुटि संदेश नहीं। मुझे कोई त्रुटि नहीं मिल रही है, न तो वांछित आउटपुट। – Karl

+1

यह प्रश्न डुप्लिकेट नहीं है: उपरोक्त संदर्भित अन्य प्रश्न में मौजूद एन्कोडिंग समस्याएं और विशेष आउटपुट प्रारूप आवश्यकताएं मौजूद नहीं हैं। – Petri

उत्तर

9

अजगर मानक पुस्तकालय (प्लस दशमलव एन्कोडिंग समर्थन के लिए simplejson) सभी है आप की जरूरत:

import csv, simplejson, decimal, codecs 

data = open("in.csv") 
reader = csv.DictReader(data, delimiter=",", quotechar='"') 

with codecs.open("out.json", "w", encoding="utf-8") as out: 
    for r in reader: 
     for k, v in r.items(): 
     # make sure nulls are generated 
     if not v: 
      r[k] = None 
     # parse and generate decimal arrays 
     elif k == "loc": 
      r[k] = [decimal.Decimal(n) for n in v.strip("[]").split(",")] 
     # generate a number 
     elif k == "geonameid": 
      r[k] = int(v) 
     out.write(simplejson.dumps(r, ensure_ascii=False, use_decimal=True)+"\n") 

कहाँ "in.csv" अपने बड़े csv फ़ाइल में शामिल है। उपर्युक्त कोड को पाइथन 2.6 & 2.7 पर काम करने के रूप में परीक्षण किया जाता है, जिसमें लगभग 100 एमबी सीएसवी फ़ाइल है, जो एक उचित एन्कोडेड यूटीएफ -8 फ़ाइल का उत्पादन करती है। अनुरोध के अनुसार आसपास के ब्रैकेट, सरणी उद्धरण और न ही अल्पविराम delimiters के बिना।

यह भी ध्यान देने योग्य है कि एन्कोडिंग के लिए सुनिश्चित करने के लिए सुनिश्चित_ascii और use_decimal पैरामीटर दोनों को गुजरना आवश्यक है (इस मामले में)।

अंत में, based on simplejson होने के कारण, पायथन stdlib जेसन पैकेज को जल्द ही या बाद में दशमलव एन्कोडिंग समर्थन भी प्राप्त होगा। तो अंत में केवल stdlib की आवश्यकता होगी।

+0

पेट्री, धन्यवाद, यह काम किया! आप सबसे अच्छे हो! क्या सीएसवी के रूप में आउटपुट को ऑर्डर करना संभव है और इसे geonameid फ़ील्ड को स्ट्रिंग बनाने के बजाय संख्या के रूप में संरक्षित करना संभव है? लिपि ने geonameid क्षेत्र में उद्धरण जोड़ा। – Karl

+0

उदाहरण अपडेट किया गया है इसलिए geonameid को एक संख्या में भी एन्कोड किया गया है।क्या आदेश वास्तव में यहां मायने रखता है, या क्या आप सिर्फ अपनी खातिर पूर्णता के लिए लक्ष्य रखते हैं? :) आप एक नियमित csv.reader का उपयोग करने के लिए स्विच कर सकते हैं, पहले हेडर पंक्ति पढ़ें: 'headers = reader.next()' और बाद में प्रत्येक पंक्ति के लिए क्रमबद्ध शब्दकोश उत्पन्न करने के लिए इसका उपयोग करें, यानी। 'आर = ऑर्डर्ड डिक्ट (ज़िप (हेडर, पंक्ति))'। इसे आज़माएं, मुझे यकीन है कि आप इसे काम कर सकते हैं। – Petri

+0

मैंने देखा है कि वैकल्पिक नाम फ़ील्ड क्वेरी के साथ बहुत धीमी गति से काम करता है क्योंकि पूरे क्षेत्र को एक स्ट्रिंग के रूप में माना जाता है। यदि वैकल्पिक नाम प्रत्येक उद्धरण के भीतर रखे गए थे तो खोज बहुत तेज होगा और फ़ील्ड को सरणी में बनाया गया था। फ़ील्ड इस तरह दिखेगा: 'alternatenames: [" ज़मीन सुखतेह "," ज़मीन सुखतेह "]' क्या यह पाइथन के साथ ऐसा करने के लिए समाधान को अपडेट करना संभव है? मुझे लगता है कि जो कोई भी geonames डेटाबेस को MongoDB में कनवर्ट कर सकता है, उसे यह बेहतर लगेगा क्योंकि फ़ील्ड पर क्वेरी वर्तमान में संभव नहीं है। – Karl

3

शायद तुम

mongoimport -d <dB> -c <collection> --type csv --file location.csv --headerline 
+0

इस दृष्टिकोण ने मुझे अपने सर्वरों में से एक पर बहुत मेमोरी बचाई v। एक पायथन स्क्रिप्ट चला रही है जो पहले .csv फ़ाइल को पढ़ती है। – andrewwowens

+0

मुझे यह सुनकर बहुत खुशी हुई कि :-) –