5

Geonames.orgからの300万行に相当する都市情報を含む300mbのCSVがあります。このCSVをJSONに変換して、mongoimportを使用してMongoDBにインポートしようとしています。JSONが必要な理由は、地理空間インデックスで使用する文字列ではなく、「loc」フィールドを配列として指定できるためです。CSVはUTF-8でエンコードされています。

CSVのスニペットは次のようになります。

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

mongoimportで機能する目的のJSON出力(文字セットを除く)は次のとおりです。

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

利用可能なすべてのオンラインCSV-JSONコンバーターを試しましたが、ファイルサイズが原因で機能しません。私が得た最も近いものは、ドキュメント間の開始ブラケットと終了ブラケット、およびコンマを削除した後にMongoDbにインポートするMr Data Converter (上の写真のもの)でした。残念ながら、そのツールは300MBのファイルでは機能しません。

上記のJSONはUTF-8でエンコードされるように設定されていますが、それでも文字セットの問題があります。おそらく変換エラーが原因ですか?

私は過去3日間、Pythonの学習、Python CSVKITの使用、スタックオーバーフローでのすべてのCSV-JSONスクリプトの試行、MongoDBへのCSVのインポート、配列への「loc」文字列の変更(残念ながら引用符は保持されます)、さらには手動での試行にも費やしました。一度に30,000レコードをコピーして貼り付けます。多くのリバースエンジニアリング、試行錯誤など。

上記のCSVのように適切なエンコーディングを維持しながら、上記のJSONを実現する方法を知っている人はいますか?私は完全に停止しています。

4

2 に答える 2

9

Python 標準ライブラリ (および 10 進エンコードをサポートするための 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ファイルが含まれています。上記のコードは、適切にエンコードされた UTF-8 ファイルを生成する約 100MB の csv ファイルを使用して、Python 2.6 および 2.7 で動作することがテストされています。要求に応じて、括弧、配列の引用符、コンマ区切り記号を使用しないでください。

また、エンコーディングが適切に機能するためには、ensure_ascii パラメーターと use_decimal パラメーターの両方を渡す必要があることにも注意してください (この場合)。

最後に、simplejson に基づいているため、python stdlib jsonパッケージも遅かれ早かれ 10 進エンコードのサポートを取得します。したがって、最終的に必要になるのは stdlib だけです。

于 2012-11-20T18:44:29.577 に答える
3

たぶん、csvをmongodbに直接インポートしてみることができます

mongoimport -d <dB> -c <collection> --type csv --file location.csv --headerline
于 2015-09-17T12:25:00.047 に答える