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

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

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

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

JSON

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

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

3回答

4143閲覧

ExcelやCSVの表形式から、入れ子の形式のJsonに変換したい

syayo

総合スコア22

CSV

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

JSON

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

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2023/04/10 05:57

編集2023/04/10 07:58

やりたいこと

ExcelやCSVの表形式のデータをJsonファイルに出力するにはどのようにしたらいいでしょうか?
Pandasを使ってやってみたりしましたが、そもそもどこからやっていいかわからず質問させていただきました。

追記

階層1の中に階層2、階層3を入れていきたいのと、
階層の深さによらず、最下層と所有者を辞書形式にしたいです。

操作前データ

階層1階層2階層3所有者
果物りんごA
果物いちごA
果物黄色ばななB
果物黄色れもんC
野菜にんじんC
野菜とまとA
野菜きゅうりB
野菜せろりA
その他B
その他黄色A

期待するoutput

JSON

1{ 2 "果物": { 3 "赤": [ 4 { 5 "りんご": "A", 6 "いちご": "A" 7 } 8 ], 9 "黄色": [ 10 { 11 "ばなな": "B", 12 "れもん": "C" 13 } 14 ] 15 }, 16 "野菜": { 17 "赤": [ 18 { 19 "にんじん": "C", 20 "とまと": "A" 21 } 22 ], 23 "緑": [ 24 { 25 "きゅうり": "B", 26 "せろり": "A" 27 } 28 ] 29 }, 30 "その他": { 31 "赤": "B.", 32 "黄色": "A" 33 } 34}

やってみたこと

以下のコードを実行してみましたが、その他の最終階層に所有者の値が入りません。

Python

1import pandas as pd 2import json 3 4# Read the Excel file 5df = pd.read_excel('sample.xlsx') 6 7# Create a dictionary to hold the data 8data = {} 9 10# Iterate over the rows of the DataFrame 11for index, row in df.iterrows(): 12 # Create a reference to the dictionary for the current row 13 current_dict = data 14 15 # Iterate over the values in the row 16 for i, value in enumerate(row[:-1]): 17 # If the value is not empty, use it as a key in the dictionary 18 if not pd.isna(value): 19 # If the key does not exist in the dictionary, create it 20 if value not in current_dict: 21 # If this is the last column, the value is the owner 22 if i == len(row)-2: 23 current_dict[value] = row[-1] 24 # Otherwise, create a new dictionary 25 else: 26 current_dict[value] = {} 27 # Update the reference to the dictionary for the current row 28 current_dict = current_dict[value] 29 30# Convert the dictionary to JSON and write it to a file 31with open('example.json', 'w') as f: 32 json.dump(data, f, ensure_ascii=False, indent=4)

出力結果(example.json)

Json

1{ 2 "果物": { 3 "赤": { 4 "りんご": "A", 5 "いちご": "A" 6 }, 7 "黄色": { 8 "ばなな": "B", 9 "れもん": "C" 10 } 11 }, 12 "野菜": { 13 "赤": { 14 "にんじん": "C", 15 "とまと": "A" 16 }, 17 "緑": { 18 "きゅうり": "B", 19 "せろり": "A" 20 } 21 }, 22 "その他": { 23 "赤": {}, 24 "黄色": {} 25 } 26}

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

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

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

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

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

can110

2023/04/10 06:03

操作前データからどのようなルール(仕様)によって期待するoutputのような構造になるのかを記載ください。
syayo

2023/04/10 06:07

コメントありがとうございます。 階層1の中に階層2、階層3を入れていきたいのと、 階層の深さによらず、最下層と所有者を辞書形式にしたいです。 質問にも追記いたしました。
melian

2023/04/10 06:18

"階層1": { "赤": [ ... の "階層1" は "果物" ではないでしょうか? また同様に、"階層2": { "赤": [ ... の "階層2" は "野菜" かと思いますが。
syayo

2023/04/10 06:22

melian さんのおっしゃる通りです。 質問のJSONを修正いたしました。
TakaiY

2023/04/10 06:31

階層3に同じキーが現われた場合、どのように対応すべきですか? "赤": [ { "りんご": "A", "いちご": "A" "いちご": "B" } というデータは作れないという意味です。
syayo

2023/04/10 06:35

階層3に同じキーが現れた場合は考慮していませんでした。 errorになってしまうかと思いますので、そのような表データは使用しないというルールで運用したいです。
guest

回答3

0

ベストアンサー

今のコードに近い形でやるなら、次に入れるキーという形で、ひとつ前のループの変数を持っておくようにすればできそうです。

python

1data = {} 2 3for index, *row in df.itertuples(): 4 current_dict = data 5 key = row[0] # 次に入れるキー 6 for value in row[1:-1]: 7 if not pd.isna(value): 8 if key not in current_dict: 9 current_dict[key] = {} 10 current_dict = current_dict[key] 11 key = value 12 current_dict[key] = row[-1]

投稿2023/04/11 03:50

bsdfan

総合スコア4567

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

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

syayo

2023/04/11 04:19

ありがとうございます! 教えていただいたコードで実行したところ、うまくいきました。 先に回答して頂いた方にベストアンサーは上げてしまいましたが、本当にありがとうございます。
guest

0

python

1import io 2import pandas as pd 3import numpy as np 4import json 5 6csv_data = ''' 7階層1,階層2,階層3,階層4,所有者 8果物,赤,りんご,,A 9果物,赤,いちご,甘い,A 10果物,黄色,ばなな,,B 11果物,黄色,れもん,酸っぱい,C 12野菜,赤,にんじん,,C 13野菜,赤,とまと,甘い,A 14野菜,緑,きゅうり,,B 15野菜,緑,せろり,,A 16その他,赤,,,B 17その他,黄色,,,A 18''' 19 20# 21def nested_dict(df): 22 l = len(df.columns) 23 if l == 1: 24 return df.values[0][0] #if df.values.size == 1 else df.values.squeeze() 25 if df.values[0][0] is np.nan: 26 idx = df.iloc[0].first_valid_index() 27 if idx == df.columns[-1]: 28 return df.values[0][-1] 29 df = df.loc[:,idx:] 30 grp = df.groupby(df.columns[0], sort=False, dropna=False) 31 return {k: nested_dict(g.iloc[:,1:]) for k, g in grp} 32 33dic = nested_dict(df) 34js = json.dumps(dic, ensure_ascii=False, indent=2) 35print(js) 36 37# { 38# "果物": { 39# "赤": { 40# "りんご": "A", 41# "いちご": { 42# "甘い": "A" 43# } 44# }, 45# "黄色": { 46# "ばなな": "B", 47# "れもん": { 48# "酸っぱい": "C" 49# } 50# } 51# }, 52# "野菜": { 53# "赤": { 54# "にんじん": "C", 55# "とまと": { 56# "甘い": "A" 57# } 58# }, 59# "緑": { 60# "きゅうり": "B", 61# "せろり": "A" 62# } 63# }, 64# "その他": { 65# "赤": "B", 66# "黄色": "A" 67# } 68# }

投稿2023/04/10 10:20

編集2023/04/11 03:36
melian

総合スコア19796

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

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

syayo

2023/04/11 02:47

回答頂きありがとうございます。 回答内容で狙いのデータは変換できましたが、階層4、5と階層が増えた場合も対応したく、実際に試したところ、どうしてもNaNがJsonに入ってしまいます。 例えば以下のような階層が深くなった場合のコードはどこを修正すればよろしいでしょうか? csv_data = ''' 階層1,階層2,階層3,階層4,所有者 果物,赤,りんご,,A 果物,赤,いちご,甘い,A 果物,黄色,ばなな,,B 果物,黄色,れもん,酸っぱい,C 野菜,赤,にんじん,,C 野菜,赤,とまと,甘い,A 野菜,緑,きゅうり,,B 野菜,緑,せろり,,A その他,赤,,,B その他,黄色,,,A '''
melian

2023/04/11 03:38

修正しましたが、入力データによっては NaN が残ってしまうかもしれません。
syayo

2023/04/11 04:14

ありがとうございます。目的とした出力を確認できました。 早急にご回答いただき、ありがとうございました。
syayo

2023/04/11 05:46

すみません。 期待する結果だと思っていましたが、少し違いました。 細かいですが、再度質問させていただきます。 最終階層まで{}でくくられていますが、期待する出力は、最終階層の辞書が[]の中に{}が入る形式になっております。 今形式にアウトプットできますでしょうか? 期待する結果 { "果物": { "赤": [ { "りんご": "A", "いちご": "A" } ], "黄色": [ { "ばなな": "B", "れもん": "C" } ] }, "野菜": { "赤": [ { "にんじん": "C", "とまと": "A" } ], "緑": [ { "きゅうり": "B", "せろり": "A" } ] }, "その他": { "赤": "B.", "黄色": "A" } }
melian

2023/04/11 05:50

はい、可能です。ですが、時間が取れないので他の方の回答をベストアンサーにしていただいて構いません。よろしくお願いします。
guest

0

DataFrameでこういうことをするのは苦手なので、ベタなやりかたです。 質問のコードもDFっぽくはない作りのようですが。
また、3階層限定です。「階層の深さによらず、最下層と所有者を辞書形式にしたい」というのはちょっと難しいような。

python

1import csv 2 3out_data = {} 4 5with open('test.csv', mode='r') as inf: 6 reader = csv.DictReader(inf) 7 for row in reader: 8 cat1 = out_data.get(row['階層1'], {}) 9 cat2 = cat1.get(row['階層2'], {}) 10 cat2[row['階層3']] = row['所有者'] 11 cat1[row['階層2']] = cat2 12 out_data[row['階層1']] = cat1

投稿2023/04/10 10:12

TakaiY

総合スコア12765

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

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

syayo

2023/04/11 02:52

回答して頂きありがとうございます。 そうですよね、私の方でも階層を3に固定であればできそうだと思っていましたが、階層の変化に対応するのに苦戦しております。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問