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

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

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

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

pandas

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

Q&A

解決済

1回答

3235閲覧

pandasのDataFrameでlist型の要素を複数行に展開する方法

k4151

総合スコア1

Python

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

pandas

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

0グッド

1クリップ

投稿2020/07/29 05:40

前提

初歩的な質問になってしまい申し訳ございません。
pythonでDataFrame内のlist型の要素を複数行に展開して、新たにDataFrameを作成したいと考えております。
下記の様なDataFrameから、infoの要素を展開させたいです。
その際に、list内のdictをカラムとして、新たに列を追加する方法をご教授いただけると幸いです。

idmenu_idinfo
110[{"name":"bread","price":100}, {"name":"rice","price":200}]
220Nan
330[{"name":"curry","price":300}]

やりたいこと

listを要素を複数行に展開し、その中にあるdictをカラムとして新たな列を追加したいです。
下記の様な結果をイメージしております。

idmenu_idnameprice
110"bread"100
110"rice"200
220NanNan
330"curry"300

試したこと

python

1tmp_df = df.set_index('id')['info'].apply(pd.Series).unstack().reset_index(1).rename(columns={0:'info'}) 2res = df[['id', 'menu_id']].merge(tmp_df, on='id')

listを複数行に展開することは出来たのですが、infoがNanの部分についても複数行作成されてしまい、失敗となりました。

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

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

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

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

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

guest

回答1

0

ベストアンサー

以下のような感じでできます。
参考:Pandas column of lists, create a row for each list element

Python

1import pandas as pd 2import numpy as np 3 4df = pd.DataFrame({'id':[1,2,3], 'menu_id':[10,20,30], 'info':[[{"name":"bread","price":100}, {"name":"rice","price":200}], np.nan, [{"name":"curry","price":300}]]}) 5print(df) 6# id menu_id info 7#0 1 10 [{'name': 'bread', 'price': 100}, {'name': 'ri... 8#1 2 20 NaN 9#2 3 30 [{'name': 'curry', 'price': 300}] 10 11# 'info'列の要素をSeriesに 12def to_sr(info, key): 13 # リストはSeriesに 14 if type(info) is list: 15 lst = [e[key] for e in info] 16 return pd.Series(lst) 17 18 # NaNなどのリスト以外は要素が1個のSeriesに 19 return pd.Series([info]) 20 21# Seriesに展開 22series = {} 23for key in ['name', 'price']: 24 f = lambda row: to_sr(row['info'], key) 25 series[key] = df.apply(f, axis=1).stack().reset_index(level=1, drop=True) 26 27# 各SeriesをDataFrameに結合し元dfに結合 28dfs = pd.DataFrame(series) 29df = df.drop('info', axis=1).join(dfs).reset_index(drop=True) 30print(df) 31# id menu_id name price 32#0 1 10 bread 100.0 33#1 1 10 rice 200.0 34#2 2 20 NaN NaN 35#3 3 30 curry 300.0

投稿2020/07/29 07:08

編集2020/07/29 07:47
can110

総合スコア38266

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

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

k4151

2020/07/29 07:36

ご回答頂きありがとうございます。 やはり関数を作成しそちらで処理させるのがよさそうですね。 仮にinfo内の要素が多数ある場合に、別で関数を作成せずに実装できる方法をご存じでしたら、ご教授いただけると幸いです。
can110

2020/07/29 07:47

関数をlambdaで作りこめばできます。回答修正しました。
k4151

2020/07/29 08:55

迅速に回答頂きありがとうございます。 実装することができました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問