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

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

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

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

Python

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

pandas

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

Q&A

解決済

1回答

1122閲覧

Python groupby count  質問です

lovely

総合スコア28

COUNT

COUNT は、広く使用されているSQLの関数です。COUNT関数は、行数、もしくは配列のエンティティの数をカウントします。

GROUP BY

GROUP BYとはSQL文のひとつで、SELECT文において特定の列の値が等しい行ごとに表をグループ化します。

Python

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

pandas

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

0グッド

1クリップ

投稿2021/08/22 02:17

質問です。

wineのデータ(qualityとその他情報)を、品質ごとにグループ分けしてその数を数える、ということをやろうとしています。コードは以下の通りです。

python

1import pandas as pd 2 3wine=pd.read_csv("winequality-white.csv", sep=";", encoding="utf-8") 4 5count_data=wine.groupby("quality")["quality"].count() 6print(count_data)

これでエラー無く実行できました。ですが、一つ疑問があります。
「count_data=wine.groupby("quality")["quality"].count()」ここの部分はどういう構造になっているのですか??groupby("quality")までは、groupbyの特性としてqualityごとにグループ分けをしていることが理解できるのですが、それ以降の部分が理解できません。

ご回答お願い致します。

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

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

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

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

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

ppaul

2021/08/22 04:00

理解するためにはかなりの基礎知識が必要です。 そこまで勉強する気はありますか?
lovely

2021/08/22 08:46

ppaulさん、ご回答ありがとうございます。ある程度の基礎は勉強してきたつもりですが足りなかったですか。。。もちろん勉強する気あります!ご教授お願い致します!!
guest

回答1

0

ベストアンサー

  • count_data=wine.groupby("quality")["quality"].count() はなにをやっているか。

複雑でわかりにくいものはバラバラにして調べるのが常道です。

  • wine.groupby("quality")の調べ方

python

1>>> print(wine.groupby("quality")) 2<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000027613BAE070> 3>>> print(type(wine.groupby("quality"))) 4<class 'pandas.core.groupby.generic.DataFrameGroupBy'>

これが何かを調べるために、以下を実行してみてください。

python

1>>> print(pd.core.groupby.generic.DataFrameGroupBy) 2<class 'pandas.core.groupby.generic.DataFrameGroupBy'> 3>>> print(pd.core.groupby.generic) 4<module 'pandas.core.groupby.generic' from 'C:\Users\myname\anaconda3\lib\site-packages\pandas\core\groupby\generic.py'>

これが意味するのは、以下の二点です。
0. pandas.core.groupby.genericというモジュールは'C:\Users\myname\anaconda3\lib\site-packages\pandas\core\groupby\generic.py'というファイルを読んで作られている。
0. wine.groupby("quality")は、pandas.core.groupby.genericというモジュールの中で定義されているクラスDataFrameGroupByのインスタンスである。

モジュールについては、公式ドキュメント チュートリアル 6. モジュールをお読みください。
クラとインスタンスについては、公式ドキュメント チュートリアル 9. クラスをお読みください。

  • groupby("quality")までは、groupbyの特性としてqualityごとにグループ分けをしていることが理解できる

それは誤解です。
groupby("quality")メソッドでDataFrameGroupByのインスタンスを作成しましたが、まだグループ分けはしていません。

python

1>>> for key,value in wine.groupby("quality").__dict__.items(): 2... print(key, ':', value) 3... 4_selection : None 5level : None 6as_index : True 7keys : quality 8sort : True 9group_keys : True 10squeeze : False 11observed : False 12mutated : False 13dropna : True 14obj : fixed acidity volatile acidity citric acid residual sugar ... pH sulphates alcohol quality 150 7.0 0.27 0.36 20.7 ... 3.00 0.45 8.8 6 161 6.3 0.30 0.34 1.6 ... 3.30 0.49 9.5 6 172 8.1 0.28 0.40 6.9 ... 3.26 0.44 10.1 6 18... ... ... ... ... ... ... ... ... ... 194895 6.5 0.24 0.19 1.2 ... 2.99 0.46 9.4 6 204896 5.5 0.29 0.30 1.1 ... 3.34 0.38 12.8 7 214897 6.0 0.21 0.38 0.8 ... 3.26 0.32 11.8 6 22[4898 rows x 12 columns] 23axis : 0 24grouper : <pandas.core.groupby.ops.BaseGrouper object at 0x0000027613BE6EE0> 25exclusions : {'quality'}

をみればわかるように、作られたDataFrameGroupByのインスタンスの属性objにはデータフレームwineがそのまま入っているだけです。まだグループ分けはしていません。

  • wine.groupby("quality")["quality"]の調べ方

初心者のうちは、ここが一番わかりにくいでしょう。

python

1[]は特殊メソッド__getitem__を呼び出します。 2 3>>> wine.groupby("quality").__getitem__ 4<bound method DataFrameGroupBy.__getitem__ of <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000027613BAE070>> 5 6なぜ__getitem__を呼び出すかは以下読んでください。

公式ドキュメント 言語リファレンス 3.3.7. コンテナをエミュレートする

wine.groupby("quality")["quality"]とwine.groupby("quality").getitem("quality")が同じことをやっているのを確認するには、以下を実行してみてください。

python

1>>> wine.groupby("quality").__getitem__("quality") 2<pandas.core.groupby.generic.SeriesGroupBy object at 0x0000027613CCC4F0> 3>>> print(wine.groupby("quality")["quality"]) 4<pandas.core.groupby.generic.SeriesGroupBy object at 0x0000027613CFB670>

アドレスが違うのは二回呼び出しているためで、中身は同じです。
wine.groupby("quality")["quality"]が何であるかを調べるために、以下を実行してみてください。

python>>>

1<class 'pandas.core.groupby.generic.SeriesGroupBy'>

これからわかるように、wine.groupby("quality")は、クラスDataFrameGroupByのインスタンスであったのに対して、wine.groupby("quality")["quality"]はクラスSeriesGroupByのインスタンスです。

どこが違うのかを調べるために以下を実行してみてください。

python

1>>> for key,value in wine.groupby("quality")["quality"].__dict__.items(): 2... print(key, ':', value) 3... 4_selection : quality 5level : None 6as_index : True 7keys : None 8sort : True 9group_keys : True 10squeeze : False 11observed : False 12mutated : False 13dropna : True 14obj : 0 6 151 6 162 6 17 .. 184895 6 194896 7 204897 6 21Name: quality, Length: 4898, dtype: int64 22axis : 0 23grouper : <pandas.core.groupby.ops.BaseGrouper object at 0x0000027613CBC670> 24exclusions : set()

つまり、wine.groupby("quality").__dict__と比べると、wine.groupby("quality")の場合は属性objがDataFrameでしたが、wine.groupby("quality")["quality"]では属性objがSeriesに変わっています。

  • countは何をしているか。

この場合、countはpandas.core.groupby.generic.SeriesGroupByというクラスのインスタンスメソッドです。

python

1>>> type(wine.groupby("quality")["quality"]).__dict__['count'] 2<function SeriesGroupBy.count at 0x000002761396B700>

このメソッドの説明だけでよければ、以下で読むことができます。(英語です)

python

1print(wine.groupby("quality")["quality"].count.__doc__)

このメソッドが何をやっているかを本当に知りたければsite-packages/pandas/core/groupby/generic.pyの804行目あたりにある、「def count(self)」からはじまるメソッド定義を読めば良いのです。

pandasの公式マニュアルは、pandas.DataFrame.groupby
とかpandas.Series.groupby
なのですが、あまり詳しく書いていないので、最後はソースを読むしかありません。

投稿2021/08/23 12:43

ppaul

総合スコア24666

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

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

lovely

2021/08/24 09:10

ppaulさん、とても丁寧なご説明ありがとうございます!! つまり、全体の流れとしては 1,wine.groupby("quality")でwineのquality,quality以外のデータを読み込む。 2,list的な奴を作りたいけど、膨大な量書くのを避けるため、又quality基準で数えるためににgetitemを呼び出す。そのためにwine.groupby("quality").getitem("quality")と書こうと思ったけど、objが変わってしまうので「wine.groupby("quality")["quality"]」を使う。 のような感じですか?? でもまだ一つ分からないことがあって、どうしてobjがwine.groupby("quality").getitem("quality")とwine.groupby("quality")["quality"]で変わってしまうのですか? ご返信お願い致します。
ppaul

2021/08/24 10:50

2,list的な奴を作りたいけど、膨大な量書くのを避けるため、又quality基準で数えるためににgetitemを呼び出す。そのためにwine.groupby("quality").getitem("quality")と書こうと思ったけど、objが変わってしまうので「wine.groupby("quality")["quality"]」を使う。 のような感じですか?? 違います。 それを理解するために、 https://docs.python.org/ja/3/reference/datamodel.html?highlight=__call__#emulating-container-types を読んでくださいと書いてあります。 どうしてobjがwine.groupby("quality").getitem("quality")とwine.groupby("quality")["quality"]で変わってしまうのですか? それの説明が「アドレスが違うのは二回呼び出しているためで、中身は同じです。」です。
lovely

2021/08/24 11:12

ご返信ありがとうございます。 英語の文章を読みましたが、count()を使うときはwine.groupby("quality")["quality"]を使うのが推奨されている、ということですか?
ppaul

2021/08/26 02:26

countは数を数えるので[]に入れるのはどの列名でも良いです。この場合だと"quality"があるのは確実なので、そう書けば間違いないということですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問