質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

1668閲覧

複数のJSONファイルをCSVファイルに変換する際、キーが存在しない箇所を0にしたい

rikku_3413

総合スコア11

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/06/16 07:04

編集2021/06/23 12:29

前提・実現したい内容

約1万ファイル、50万行ほどの膨大な量のJSONファイルを1つのCSVファイルにまとめたいです。
しかし複数のファイルにおいてデータが入っていない箇所があり、全ファイルを網羅的に変換してCSVファイルにまとめるとデータが入っていない部分が詰められてしまう状態です。

実現したい内容は以下の3点です。

  • 複数JSONファイルを1行のCSVに変換して1つのCSVファイルに変換する
  • 最初に変換したファイルのキーを参照して2つ目以降のファイルの変換を行う
  • キーが一致する場所にデータを書き込み、キーが存在しなければ0を代入する

該当のソースコード

以下に記述しているのは実際に使用しているPythonコードです。現在の仕様では、「ネストされたJSONファイルをキーと共に出力する」となっています。

Python

1import sys 2import json 3import csv 4import io 5 6 7def to_string(s): 8 try: 9 return str(s) 10 except: 11 #Change the encoding type if needed 12 return s.encode('utf-8') 13 14def reduce_item(key, value): 15 global reduced_item 16 17 #Reduction Condition 1 18 if type(value) is list: 19 i=0 20 for sub_item in value: 21 reduce_item(key+'_'+to_string(i), sub_item) 22 i=i+1 23 24 #Reduction Condition 2 25 elif type(value) is dict: 26 sub_keys = value.keys() 27 for sub_key in sub_keys: 28 reduce_item(key+'_'+to_string(sub_key), value[sub_key]) 29 30 #Base Condition 31 else: 32 reduced_item[to_string(key)] = to_string(value) 33 34 35if __name__ == "__main__": 36 if len(sys.argv) != 4: 37 print ("\nUsage: python json_to_csv.py <node> <json_in_file_path> <csv_out_file_path>\n") 38 else: 39 #Reading arguments 40 node = sys.argv[1] 41 json_file_path = sys.argv[2] 42 csv_file_path = sys.argv[3] 43 44 with io.open(json_file_path, 'r', encoding='utf-8-sig') as fp: 45 json_value = fp.read() 46 raw_data = json.loads(json_value) 47 48 try: 49 data_to_be_processed = raw_data[node] 50 except: 51 data_to_be_processed = raw_data 52 53 processed_data = [] 54 header = [] 55 for item in data_to_be_processed: 56 reduced_item = {} 57 reduce_item(node, item) 58 59 header += reduced_item.keys() 60 61 processed_data.append(reduced_item) 62 63 header = list(set(header)) 64 header.sort() 65 66 with open(csv_file_path, 'a') as f: 67 writer = csv.DictWriter(f, header, quoting=csv.QUOTE_ALL) 68 writer.writeheader() 69 for row in processed_data: 70 writer.writerow(row) 71 print ("Just completed writing csv file with %d columns" % len(header))

###変換するファイルの例
行数が非常に多いため、適宜省略して載せています。...が省略箇所です。

{ "devices":[ { "name": "IntGW-01", "modules": { "openconfig-interfaces": { "interfaces": { "interface": [ { "name": "GigabitEthernet1", "config": { "name": "GigabitEthernet1", "type": "ianaift:ethernetCsmacd", "description": "ManagementIF", "enabled": true }, "state": { "name": "GigabitEthernet1", "type": "ianaift:ethernetCsmacd", "enabled": true, "ifindex": 1, "admin-status": "UP", "oper-status": "UP", "last-change": 1580105229000389000, "counters": { "in-octets": 17493436676, ... "out-errors": 0, "last-clear": 1580105112000091000 } }, "subinterfaces": { "subinterface": [ { "index": 0, "config": { "index": 0, "description": "ManagementIF", "enabled": true }, "state": { "enabled": true, "name": "GigabitEthernet1", "ifindex": 1, "admin-status": "UP", "oper-status": "UP", "last-change": 1580105229000389000, "counters": { "in-octets": 17493436676, ... "out-errors": 0, "last-clear": 1580105112000091000 } } } ] } }, { "name": "GigabitEthernet2", "config": {            〜上記GigabitEthernet1と同じ構成のものが8個〜 ] } },     "ietf-interfaces": { ... },     "Cisco-IOS-XE-interfaces-oper": { ... },     "Cisco-IOS-XE-bgp-oper": { ... },     "Cisco-IOS-XE-platform-software-oper": { ... },     "Cisco-IOS-XE-memory-oper": { ... } } }, { "name": "IntGW-02", "modules": { ... 〜以下同じ構造のものが4つ〜 } } ], "@log_name": "network-device-bgpnw2" }

このプログラムをシェルスクリプトを用いて網羅的な処理をしています。

sh

1#!/bin/bash 2 3dir_path="(フォルダパス)" 4dirs=`find $dir_path -maxdepth 0 -type f -name *.json` 5 6for dir in $dir_path; 7do 8 echo $dir 9 python json_to_csv.py(上記Pythonファイル) computes $dir physical-data.csv 10done

###その他
「キーを参照して一致すれば書き込み、なければ0」の処理方法が分からず苦戦しています。
拙い日本語ではありますが、教えて頂ければと思います。

###追記
編集願に「実行した時のCSVファイルと実現したいCSVファイルを載せてほしい」というものがありましたが、出力ファイルが非常に大きく、開こうとすると重すぎてまともに開けないという状況にあります。そのため実際の出力ファイルの中身は示すことができませんが、このような雰囲気の出力をしたいというものを書かせていただいております。

###実際の出力
2つのファイルを処理したとき、2つ目のJSONファイルにキーがCの要素がなかったとしています。スクリプトで処理しているため、キーが処理した回数分表示されます。

CSV

1"A","B","C","D" 21,2,3,4 3"A","B","D" 45,6,7

###実現したい出力

CSV

1"A","B","C","D" 21,2,3,4 35,6,0,7 4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Thrush

2021/06/17 14:15

どういう結果を得たいのかをもう少し詳しく説明していただけると解答しやすいです。 以下のファイルを添付するのが最も簡単です ① 実装したコード ② inputするjsonファイルの例 ③ ②をinputした際、実際に出力されるcsvファイル ④ ②をinputした際、出力したいcsvファイル
rikku_3413

2021/06/23 12:48

要望になるべく添えるように修正を加えました。 確認の方をよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問