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

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

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

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

pandas

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

Q&A

解決済

1回答

1160閲覧

Python3で特定のコラムの名前ごとにグラフを描く

Danrussia

総合スコア44

Python 3.x

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

pandas

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

0グッド

0クリップ

投稿2019/06/27 14:30

編集2019/07/09 10:53

###最初に
自分の言語能力が低いのと、実装したい事が幾らか抽象的なので、伝わりづらい所があったら、遠慮なく指摘していただけたら幸いです。

前提・実現したいこと

Pythonを用いてデータ分析(視覚化、統計的な処理)を行いたいと思っています。下記のものが
分析対象のデータセットです。データセットについて少しご説明させて頂くとコラム"Sample"には
くるみ豆、五葉黒豆、濃緑丸豆...といったようなものがそれぞれ100個ずつあります。

AreaSumpleBeanNumber
70くるみ豆B2
100くるみ豆B2
90くるみ豆B2
...
60五葉黒豆B6
65五葉黒豆B6
...
120濃緑丸豆B39
120濃緑丸豆B39
120濃緑丸豆B39
120濃緑丸豆B39
110濃緑丸豆B39

このデータセットにおいて"Sample"の名前ごとに(くるみ豆、五葉黒豆、濃緑丸豆...ぞれぞれに対して)
"Area"を基準としたグラフを描写したいと思っています。matplotlibの細かい仕様についてもまだ良くわかってはいないのですが、下の様なコードでヒストグラムを作成したいと思っています。
このコードを実行した"Sample"の値全部でグラフが描写されますが、今回の場合はSampleの名前ごとにグラフを描写したいです。

グラフ描写のコード(仮)

Python3

1import matplotlib.pyplot as plt 2import pandas as pd 3df1.distplot(df1["Area"], bins=20) 4plt.show()

試したこと

試した事というほどの事はしていないのですが、実装のアイデアとして
①データフレームのコラム●を基準にしてそれをcsvファイルなどにする。
②ひとつひとつのcsvファイルに対してその各々のファイルに指定の処理を加える。
③結果を出力する。
(参考:https://teratail.com/questions/185208)
というのは考えていたのですが、処理に時間がかかるというのと、あまりスマートなやり方ではないと感じていたのでTeratailでご質問させて頂きました。

補足情報(FW/ツールのバージョンなど)

Anaconda
Python
Pycharm
お忙しいとは思いますが、よろしくお願いいたします。
情報に不足がありましたら、ご指摘お願いいたします。

###追記: ベストアンサーにしたコードについての質問

Python3

1#コラム名の中で"Sample"で一纏めにしている 2grouped_df= df.groupby('Sample') 3 4#ここでsubplotを使ったのは、コードの性質上複数のグラグを同時に表示するから。 5#lenでSampleに合わせた数を生成してる。 6fig, axs = plt.subplots(1, len(grouped_df)) 7 8for ax, (name, df) in zip(axs, grouped_df): ここでのzipは2つの引数を渡すために設定している。 9 df['Area'].hist(ax=ax) 10 ax.set_title(name) 11plt.show()

・コード2行目の変数に"fig , ax"と入れているのですが、このfig , axがなしている意味を調べてみたのですが、公式ドキュメントにも特に何も記述がありませんでした。この変数の代わりに適当に文字を
入れてもなりたたなかったので、これは一種の仕様的なものですか?

・for文の中で”ax"を適当な文字として入れた後に"(name, df)"と入れているいるのですが、
なぜ一度もコードの中で登場がなかった"name"がグラフのタイトルを担う役割ができるのか

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

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

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

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

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

guest

回答1

0

ベストアンサー

DataFrame.groupby('Sample') の結果にてループ処理を行い、
各ループ毎にヒストグラムを描画するよいのではないでしょうか。

Python

1import pandas as pd 2import numpy as np 3import matplotlib.pyplot as plt 4 5# 適当なデータを乱数で作成 6N=120 #データ数 7df = pd.DataFrame({ 8 'Area': np.random.randint(0,100,N), 9 'Sample': np.random.choice(['くるみ豆','五葉黒豆','濃緑丸豆'],N) 10}) 11 12# 一応、以下が回答部分 13grouped_df= df.groupby('Sample') 14 15fig, axs = plt.subplots(1, len(grouped_df)) 16 17for ax, (name, df) in zip(axs, grouped_df): 18 df['Area'].hist(ax=ax) 19 ax.set_title(name) 20plt.show() 21

【コメントを受けて追記1】

順番が逆になりますが、まずは groupby() から。

一般的に DataFrame.groupby() をループで使用する場合はこんな感じで記述します。

Python

1for name, data in pd.groupby('Sample'): 2 # 何らかの処理

このようにすると、Sample列の値が同じもの同士でグループ分けして、そのグループ毎に
ループ処理がおこなわれます。またこの際に、ループにには2つの変数が渡され、

  • 1つ目(上記のコードではname)はグループ分けに使用した Sample の値、
  • 2つ目(上記のコードではdata)はグループ分けされたDataFrame

が入ります。

今回、回答で記述したコードはこの簡単なバリエーションで、別の配列 axs(後で説明)
と同期して一緒にループ処理を行う必要があったので zip() を使用して

Python

1axs = [......] # 何らかの配列 2for ax, (name, data) in enumerate(axs, pd.groupby('Sample')): 3 # 何らかの処理

という記述になっております。当然 name には グループ分けに使用した Sample の値
が入っておりますので、そのままタイトルに利用しているだけです。


【コメントを受けて追記2】

次に1つ目の件ですが、まずは

https://matplotlib.org/3.1.1/tutorials/intermediate/gridspec.html
https://qiita.com/tsuruokax/items/90167693f142ebb55a7d

あたりを読むと理解が深まるかと思います。

とりあえず、簡単に説明すると

  • figure はグラフを書くための図(を書くためのエリア)
  • axは1つ1つのグラフ

となっており、1つの図(figure)には複数のグラフ(ax)を入れる事が出来ます。
1つの図にどのようにグラフを配置するかは subplots() の引数にて設定されており、
第一引数が縦に並べるグラフ数、第二引数が横に並べるグラフの数となりますので

例えをあげると、

  • fig, axs = plt.subplots(1,4) : 横に4個グラフを並べる
  • fig, axs = plt.subplots(4,1) : 縦に4個グラフを並べる
  • fig, axs = plt.subplots(2,2) : 横2個、縦2個(計4個)のグラフを並べる

のようになります。
この時の2つめ戻り値(axs) は図に配置された各グラフが格納された配列となっておりますので、

Python

1fig, axs = plt.subplots(1,4) 2axs[0].plot() #1番目のグラフをプロット 3axs[1].plot() #2番目のグラフをプロット 4axs[2].plot() #3番目のグラフをプロット 5axs[3].plot() #4番目のグラフをプロット

のように記述することで、各グラフを描画することができます。

で、今回の回答のコードは上記の描画処理を単にループを使って

Python

1fig, axs = plt.subplots(1,4) 2for as in axs: 3 ax.plot() # 各グラフにプロット

のように記述しただけの処理となります
(前述のとおり zip を使ってデータと一緒にループされております)

この変数の代わりに適当に文字を入れてもなりたたなかったので、これは一種の仕様的なものですか?

いや、figaxs も私が勝手に決めた変数名ですので変更しても動作するはずです。

投稿2019/06/27 16:24

編集2019/07/10 00:28
magichan

総合スコア15898

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

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

Danrussia

2019/07/09 04:43

こちらの状況がばたついてしまったせいで、返答が大変遅くなってしまいました。申し訳ありません。 magichanさんに書いて頂いたコードで自分のイメージのものは実装できました。ありがとうございます。 もし可能でしたら、コードの意味が自分の理解不足で理解できない点があったのでご質問させていただけないでしょうか?
magichan

2019/07/09 05:31

大丈夫ですよ。 コメント欄でも、質問を編集でもよいので記述してください。
Danrussia

2019/07/09 10:53

質問を編集する形で記述しました。 よろしくお願いいたします。
magichan

2019/07/10 00:28

とりあえず疑問点の回答を追記しましたので確認ください
Danrussia

2019/07/13 09:19

2つの変数を渡してfor文で回すのは今まで遭遇した事なかったのと動作のイメージを持てなかったので、丁寧に説明してくださって助かりました。 subplotに関しての解説ありがとうございました。今までかなり雑に理解していたのでそこらへんが整理されて、とても分かりやすかったです。 追記2に関しては、恐らくまだ自分の中でplt.plotとax.plotの違いがよくわかっていないので、自分の中でもう少しサーベイしてみます。 こんな詳細な解説を無給でして頂いて本当に頭があがりません。ありがとうございました。 自分の中でもう少し理解度が深まったら(teratailに限らず)、知らない人に説明するようにします。 今回は本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問