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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

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

Q&A

解決済

2回答

1867閲覧

pandasのDataframeに入った辞書型データにアクセスしたい

crossism

総合スコア16

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

pandas

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

0グッド

0クリップ

投稿2019/05/28 01:08

Slackのログを解析しています。ログファイルはjson形式で、pandasのDataframeとして読み込むとreactionsが次のような形になりました。

python3

1dfMa21 = pd.io.json.json_normalize(LecMa21) 2dfMa21reacs = dfMa21[['ts','reactions']]

イメージ説明
リアクションの名前、リアクションした人のリスト、リアクション数が一つの辞書項目となって、これがあるメッセージに対するリアクションの種類の数だけリストとして入っています。
このリストを分解するために次のようなコードを書きました。

python3

1tmp = dfMa21reacs.reactions.apply(pd.Series).stack().reset_index(level=1, drop=True).rename('reactions') 2dfMa21reacs = dfMa21.loc[:,['ts']].join(tmp).reset_index(drop=True)

イメージ説明
tsはタイムスタンプなのでtsが同じ項目は同じメッセージを表します。リストが分解され、同じメッセージに付いていたリアクションが一つずつ見えるようになりました。

問題はここからです。ここで例えば'name':'yakunitatta'となっているデータを取り出す操作を行いたいのですが、どうしたらいいかわかりません。辞書型データにkeyによってアクセスする方法を調べて以下のようにしたのですが、KeyError: 'name'になってしまいます。

python3

1dfMa21useful = dfMa21reacs[dfMa21reacs.reactions['name'] == 'yakunitatta']

pandasのデータ項目として辞書型データが入っているというケースが見つけられず、質問に至りました。正しい方法、あるいはもっと効率のいい方法があれば教えていただけると幸いです。

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

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

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

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

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

guest

回答2

0

ベストアンサー

以下のようにnameも列に分離すると処理しやすいかと思います。

Python

1import pandas as pd 2 3df = pd.DataFrame({'ts':[1,1],'reactions':[{'name':'a','users':['u1','u2']}, {'name':'b','users':['u3','u4']}]}) 4 5def func(row): 6 row['name'] = row.reactions['name'] 7 row['users'] = row.reactions['users'] 8 return row 9 10df = df.apply(func, axis=1).drop('reactions',axis=1) 11print(df) 12""" 13 ts name users 140 1 a [u1, u2] 151 1 b [u3, u4] 16""" 17 18print(df[df['name'] == 'a']) 19""" 20 ts name users 210 1 a [u1, u2] 22"""

投稿2019/05/28 01:27

can110

総合スコア38233

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

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

crossism

2019/05/28 02:08

回答ありがとうございます。 can110様のコードをそのままで実験し動くのを確認したあと、dfにわたしが使っているdataframeを代入して同じコードをprint(df)まで動かしてみたところ、 TypeError: ("'float' object is not subscriptable", 'occurred at index 6') となってしまいました。みたところ例として挙げていただいたdfとほとんど構造は変わらないはずなのですが、なぜfloat扱いになってしまっているのでしょうか。もしこちらもお分かりになることがあればアドバイスをいただけるとありがたいです。
can110

2019/05/28 02:42

ちょっと思い当たる原因がないですね… 現象が再現する完全なソースコードと最小限のJSONファイルを質問に追記されると、こちらでも検証できるかもしれません。
crossism

2019/05/31 08:19

コメントが送れていなかったようで遅くに失礼します。 少し難しそうなので、もう少し検証したのち、解決しなければ改めて別の質問として投稿しようと思います。お付き合いありがとうございました。
crossism

2019/06/03 06:08

無事解決いたしました。質問中のスクリーンショットの範囲では見えないのですが実データに空の部分があり、その部分の例外処理が必要なだけでした。 わかりやすい回答ありがとうございました。
guest

0

can110様の回答で最終的に解決しました。

うまくいかなかった原因は例外処理でした。例として表示した部分は項目が必ず埋まっていましたが、実際のデータには空の部分があり、そこを弾く必要がありました。

質問する際に気をつけるべきこととしても勉強になることの多い質問となりました。
can110様に改めてお礼を申し上げます。ありがとうございました。

投稿2019/06/03 06:06

編集2019/06/03 06:23
crossism

総合スコア16

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問