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

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

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

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

Python

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

pandas

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

Q&A

解決済

3回答

4574閲覧

python jsonの配列から任意のkeyを複数指定していっぺんにvalueを取得する方法を教えてください

taiki9121

総合スコア18

JSON

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

Python

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

pandas

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

0グッド

3クリップ

投稿2020/09/18 05:58

編集2020/09/18 06:12
jsons = [{ "user": { "updatedAt": "2020-04-01", "id": "0001", "name": "taro", "status": { "level": "1", "hp": "100", "atk": "120", }, } }, { "user": { "updatedAt": "2020-04-02", "id": "0002", "name": "hanako", "status": { "level": "2", "hp": "130", "atk": "150", }, } }]

上記のようなjsonデータを用いて、string型の任意のキーのルートを示す値を渡すことで、そのキーに対応するデータをDataFarmeとして出力するように実装したのが下記になります。

def json_to_df(jsons, str_keys): keys= str_keys.split(".") res = [] for json in jsons : for i, key in enumerate(keys): if key in json : json = json [key] else: return None if i >= len(keys) - 1: res.append(json) return pd.DataFrame(res, columns=[keys[-1]])

これを実行すると

res = json_to_df(jsons, "user.name") print(res) # name 0 taro 1 hanako

のように取得できます。
ただ、求めているものは、

res= json_to_df(jsons, ["user.name","user.id","user.status.level"]) print(res) # name id level 0 taro 0001 1 1 hanako 0002 2

のように引数に複数のキールートを指定することで2つ以上のカラムを出力するようしたいです。
強引にfor文を使えばできなくもなさそうですが、2重ループにも3重ループにもなりそうで処理的に無駄が多いような気がしてなりません...
そもそもjson_to_dfのような実装じゃなくて、もっと簡単な手法などがありましたらご教授お願いします。

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

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

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

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

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

guest

回答3

0

質問が閉じてしまっているようですが。

json_normalizeをdict化されたJSONデータに適用すると
正に要望通りのDataFrame型に変換してくれるので、
後はそのDataFrameにlistでcolumn名を指定すればそのまま取得することができます。

python

1df = pd.json_normalize(jsons) 2print(df) 3''' 4 user.updatedAt user.id user.name user.status.level user.status.hp user.status.atk 50 2020-04-01 0001 taro 1 100 120 61 2020-04-02 0002 hanako 2 130 150 7''' 8 9print(df[['user.name', 'user.id', 'user.status.level']]) 10''' 11 user.name user.id user.status.level 120 taro 0001 1 131 hanako 0002 2 14'''

投稿2020/09/18 07:39

編集2020/09/18 07:43
yureighost

総合スコア2183

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

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

taiki9121

2020/09/22 07:50

ありがとうございます! pandasはまだ使い慣れていないので助かりました!
guest

0

ベストアンサー

面白そうなので作ってみました。
pandasには詳しくないので、もっと簡単に解決する方法があるかもしれませんが。

Python

1def map_getitem_(dct_lst, *attrs): 2 if not attrs: 3 return dct_lst 4 5 attr, *rest = attrs 6 return map_getitem_( 7 (dct[attr] for dct in dct_lst), *rest 8 ) 9 10def map_getitem(dct_lst, attrs_txt): 11 return map_getitem_(dct_lst, *attrs_txt.split('.')) 12 13def json_to_df(jsons, keys_txt): 14 df = pd.DataFrame( 15 data={ 16 keys: map_getitem(jsons, keys) for keys in keys_txt 17 }, 18 ) 19 df.columns = df.columns.map(lambda e: e.split('.')[-1]) 20 21 return df

Python

1print(list(map_getitem_(jsons, 'user', 'name'))) # => ['taro', 'hanako'] 2print(list(map_getitem(jsons, 'user.name'))) # => ['taro', 'hanako'] 3print( 4 json_to_df(jsons, ['user.name', 'user.id', 'user.status.level']) 5) 6# => name id level 7# 0 taro 0001 1 8# 1 hanako 0002 2

強引にfor文を使えばできなくもなさそうですが、2重ループにも3重ループにもなりそうで処理的に無駄が多いような気がしてなりません...

機能を分割して考えるとわりあい簡潔に書けます。

投稿2020/09/18 06:45

編集2020/09/18 07:13
LouiS0616

総合スコア35668

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

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

taiki9121

2020/09/18 07:25

ありがとうございます! 勉強になります
guest

0

こんにちは。
いっぺんには取れませんが、楽するために
JMESPathとかはどうでしょうか。
https://pypi.org/project/jmespath/

投稿2020/09/18 06:17

編集2020/09/18 06:20
kay-ws

総合スコア106

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問