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

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

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

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

Q&A

解決済

3回答

4873閲覧

(Python)GroupByで指定した列を含んだDataFrameを作る方法

gitiiii

総合スコア12

Python 3.x

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

0グッド

0クリップ

投稿2018/03/06 14:48

編集2018/03/06 14:56

Python初心者で、大変恐縮なのですが質問があります。

下記のようなデータを月別に集計してプロットしたいのですが、

date  sale
2018/01 100
2018/01 200
2018/02 100

csv=csv.groupby('date')["sale"].sum() plt.scatter(csv["date"], csv["sale"])

とするとKeyError: 'date'と出てしまいます。

saleはcsv["sale"]と参照できるのですが、
groupbyで指定した"date"を含めてDataFrameを作成するにはどうしたらよいでしょうか。

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

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

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

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

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

guest

回答3

0

ベストアンサー

csv.groupby('date')['sale'].sum() にて得られる結果は DataFrame ではなく、Seriesとなります。
更に groupby() した結果 'date'index として格納されておりますので csv['date'] ではなく csv.index と指定する必要があります。

ですので、このデータをプロットする際は
ax.scatter(csv.index, csv.values)
となるかと思います。

dkato0077さんの書かれている通り、Series.plot() を使う手もありますが、残念ながらSeriesでは kind='scatter' が使えないみたいです。

以下に簡単なテストサンプルを記述しました。

Python

1import pandas as pd 2import matplotlib.pyplot as plt 3import matplotlib.dates as mdates 4 5# 適当なデータを生成 6csv = pd.DataFrame({ 7 'date':['2018/01','2018/01','2018/02','2018/02','2018/03','2018/03'], 8 'sale':[100,200,100,300,100,400] 9}) 10csv['date'] = pd.to_datetime(csv.date) 11 12csv = csv.groupby('date')['sale'].sum() 13ax = plt.subplot() 14ax.scatter(csv.index, csv.values) 15ax.xaxis.set_major_locator(mdates.MonthLocator()) 16ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m")) 17plt.show()

結果を SeriesではなくDataFrameにて得たい場合は、
csv.groupby('date')['sale']
のように Column名 'sale' にて指定するのではなく、
csv.groupby('date')[ ['sale'] ]
のようにリストで指定するとよいかと思います。

ただこの場合も**'date'** は index として格納されておりますので注意してください

で、こちらの場合のプロットはこんな感じ(ほとんど同じだけど・・)

Python

1import pandas as pd 2import matplotlib.pyplot as plt 3import matplotlib.dates as mdates 4 5# 適当なデータを生成 6csv = pd.DataFrame({ 7 'date':['2018/01','2018/01','2018/02','2018/02','2018/03','2018/03'], 8 'sale':[100,200,100,300,100,400] 9}) 10csv['date'] = pd.to_datetime(csv.date) 11 12csv = csv.groupby('date')[['sale']].sum() 13ax = plt.subplot() 14ax.scatter(csv.index, csv['sale']) 15ax.xaxis.set_major_locator(mdates.MonthLocator()) 16ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y-%m")) 17plt.show()

投稿2018/03/06 23:49

magichan

総合スコア15898

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

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

退会済みユーザー

退会済みユーザー

2018/03/06 23:54

おや、動かないところがありましたか。動作の確認はしたつもりだったのですが、失礼しました。
magichan

2018/03/06 23:58

いやいや、dkato0077 さんのサンプルの場合は csv.groupby('date').sum() と全てのColumnのsum() をとる事で DataFrameとして結果を得ておりますので、全く問題ないかと思います。問題があるのは Seriesデータを Sreas.plot(kind='scatter') とした場合となります。
magichan

2018/03/06 23:58

紛らわしい記述で申し訳ありませんでした
退会済みユーザー

退会済みユーザー

2018/03/07 00:00

Siriesのほうでしたか、勘違いしました。すいません。
gitiiii

2018/03/07 10:23

ありがとうございます。正直ベストアンサーをどちらにするか大変迷ったのですが、 こちらの方が私にとっては書きやすいかなと思い、ベストアンサーとさせていただきました。
guest

0

groupby後のdataframe(csv)のインデックスにdateは残っているので、それをcsv.index.valuesで取り出して、scatterに渡せばうまくいくはずです

投稿2018/03/07 00:01

R.Shigemori

総合スコア3376

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

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

0

最初の質問に答えておりませんでした。
dateをindexにせずに列として残す場合はas_index=Falseのオプションをつければいいです。

Python

1csv = csv.groupby("date", as_index=False).sum() 2csv.plot(x="date", y="sale", style="o")

ただ、これだとplotしても軸が正しく反映されないので、dateのデータタイプをdatetimeに変更しておきます。

Python

1csv["date"] = pd.to_datetime(csv["date"]) 2csv = csv.groupby("date", as_index=False).sum() 3ax = csv.plot(x="date", y="sale", style="o") 4 5xticks = pd.date_range(csv["date"].min(), csv["date"].max(), freq="MS") 6ax.set_xticks(xticks)

最後の2行はx軸を一か月ごとにするためのものです。


以下、最初の回答

groupbyのとこにある[“sale”]を外す。

python

1csv=csv.groupby('date').sum() 2plt.scatter(csv["date"], csv["sale"])

あと、DataFrameのプロットまでやるなら

python

1csv.set_index(‘date’) 2csv = csv.groupby(‘date’).sum() 3csv.plot()

と、pandas側でやってしまう方がいいかもしれません。

投稿2018/03/06 14:54

編集2018/03/07 00:41
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

gitiiii

2018/03/06 14:57

申し訳ありません、誤字がありました。monthでなくdateとなります。
退会済みユーザー

退会済みユーザー

2018/03/07 00:48

scatterを使いたい場合はmagichanさんのほうが参考になると思います。
gitiiii

2018/03/07 10:19

ありがとうございます、とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問