【Pandas】データを集計する方法 | groupby / pivot_table

Python

【はじめに】

Pythonライブラリの「Pandas」の中で、データを集計する方法として「groupby」、「pivot_table」があります。

どちらを使った方が良いのか分からない方のために、集計の目的に応じてどちらを使用するべきか分かりやすく紹介していきます。

本記事の内容

  • pandasのインポート
  • csvファイルの読み込み
  • データを集計する | groupby
  • データを集計する | pivot_table

【pandasのインポート】

import pandas as pd

【csvファイルの読み込み】

「1920年から2015年までの全国の人口推移のデータ」を使用します。

df = pd.read_csv('data.csv', encoding='shift-jis')
df
都道府県コード都道府県名元号和暦(年)西暦(年)人口(総数)人口(男)人口(女)
01北海道大正91920235918312443221114861
12青森県大正91920756454381293375161
23岩手県大正91920845540421069424471
34宮城県大正91920961768485309476459
45秋田県大正91920898537453682444855
...........................
93443熊本県平成2720151786170841046945124
93544大分県平成2720151166338551932614406
93645宮崎県平成2720151104069519242584827
93746鹿児島県平成2720151648177773061875116
93847沖縄県平成2720151433566704619728947
939 rows × 8 columns

私のGitHubに「data.csv」としてアップロードしてあるので、下記コマンドでダウンロードすれば簡単に準備できます。

$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Pandas/data.csv -O

【データを集計する | groupby】

groupbyメソッドを使用すると、DataFrameの要素をもとにデータをグループ分けして、簡単に集計することができます。

引数byにグループ分けしたカラムを指定します。

読み込んだcsvファイルから「都道府県別」に、「人口(総数)」、「人口(男)」、「人口(女)」それぞれを集計してみます。

df_mean1 = df.groupby(by='都道府県名').mean()[['人口(総数)', '人口(男)', '人口(女)']]
df_mean1.head(10)
人口(総数)人口(男)人口(女)
都道府県名
三重県1534021.4743366.55790654.85
京都府2135317.951044093.71091224.25
佐賀県830574.25395550.75435023.5
兵庫県42335252067583.12165941.9
北海道4606104.32272235.252333869.05
千葉県3591668.11789946.81801721.3
和歌山県978371.25471085.7507285.55
埼玉県4040109.052023428.052016681
大分県1142165.05544737.95597427.1
大阪府6380772.253167758.653213013.6

ポイント

  • DataFrameに対して、はじめに「都道府県名」でグループ分けしてから、「人口(総数)」、「人口(男)」、「人口(女)」の平均を抽出しています。
  • DataFrameに対して、はじめに「都道府県名」、「人口(総数)」、「人口(男)」、「人口(女)」のデータを抽出してから「都道府県名」でグループ分けして平均を求めることもできます。
df_mean2 = df[['都道府県名', '人口(総数)', '人口(男)', '人口(女)']].groupby(by='都道府県名').mean()
df_mean2.head(10)
人口(総数)人口(男)人口(女)
都道府県名
三重県1534021.4743366.55790654.85
京都府2135317.951044093.71091224.25
佐賀県830574.25395550.75435023.5
兵庫県42335252067583.12165941.9
北海道4606104.32272235.252333869.05
千葉県3591668.11789946.81801721.3
和歌山県978371.25471085.7507285.55
埼玉県4040109.052023428.052016681
大分県1142165.05544737.95597427.1
大阪府6380772.253167758.653213013.6

groupbyメソッドで集計できるものとしては、

  • mean(平均)
  • sum(合計)
  • count(個数)
  • max(最大値)
  • min(最小値)
  • std(標準偏差)
  • var(分散)

などがあります。

複数要素でグルーピングする

groupbyメソッドの引数byにリストで複数のカラムを指定することで、複数要素での集計が可能です。

「都道府県名」と「元号」をリスト形式で指定して、「人口(総数)」、「人口(男)」、「人口(女)」それぞれの平均を集計してみます。

df_mean3 = df[['都道府県名', '元号', '人口(総数)', '人口(男)', '人口(女)']].groupby(by=['都道府県名', '元号']).mean()
df_mean3
人口(総数) 人口(男) 人口(女)
都道府県名 元号
三重県 大正 1.09E+06 5.35E+05 5.53E+05
平成 1.84E+06 8.93E+05 9.45E+05
昭和 1.46E+06 7.03E+05 7.53E+05
京都府 大正 1.35E+06 6.84E+05 6.63E+05
平成 2.63E+06 1.27E+06 1.36E+06
鳥取県 平成 6.02E+05 2.88E+05 3.14E+05
昭和 5.66E+05 2.71E+05 2.95E+05
鹿児島県 大正 1.44E+06 6.98E+05 7.46E+05
平成 1.75E+06 8.19E+05 9.29E+05
昭和 1.75E+06 8.30E+05 9.20E+05
141 rows × 3 columns

このままだと人口が指数表示となってしまい、ひと目では何人なのか分かりにくいですね。

※指数表現は数値を1桁にして、その分10を何乗したかで表現しています。

ひと目で人口が分かるように、round(0)とすることで、小数点以下を切り捨てて表現します。

df_mean3.round(0)
人口(総数) 人口(男) 人口(女)
都道府県名 元号
三重県 大正 1088481.0 535354.0 553126.0
平成 1838127.0 893168.0 944960.0
昭和 1456225.0 703135.0 753090.0
京都府 大正 1346764.0 684122.0 662642.0
平成 2628425.0 1268325.0 1360099.0
鳥取県 平成 602177.0 287885.0 314291.0
昭和 565924.0 270756.0 295169.0
鹿児島県 大正 1443888.0 697972.0 745915.0
平成 1747640.0 818506.0 929134.0
昭和 1749826.0 829889.0 919936.0
141 rows × 3 columns

aggメソッドを使って集計する

aggメソッドは平均や合計などを同時に集計することができます。

集計したい計算方法をaggメソッドの引数にリストで指定します。

「都道府県名」と「元号」をリスト形式で指定して、「人口(総数)」、「人口(男)」、「人口(女)」それぞれの平均、最大値、最小値を集計してみます。

df_culc1 = df[['都道府県名', '元号', '人口(総数)', '人口(男)', '人口(女)']].groupby(by=['都道府県名', '元号']).agg(['mean', 'max', 'min'])
df_culc1.round(0)
人口(総数)人口(男)人口(女)
meanmaxminmeanmaxminmeanmaxmin
都道府県名元号
三重県大正108848111076921069270535354544752525957553126562940543313
平成183812718669631792514893168907214869515944960959749922999
昭和145622517473111157407703135847420571000753090899891586407
京都府大正134676414063821287147684122717464650780662642688918636367
平成262842526476602602460126832512781421248972136009913746671334840
.................................
鳥取県平成602177615722573441287885294899273705314291320823299736
昭和565924616024484390270756297015233964295169320513250182
鹿児島県大正144388814721931415582697972713702682243745915758491733339
平成174764017978241648177818506842474773061929134955350875116
昭和1749826204411215384668298899856176994559199361058495803046
141 rows × 9 columns

ポイント

統計量を算出したい場合は、aggメソッドの引数にdescribeを指定します。

「都道府県名」と「元号」をリスト形式で指定して、「人口(総数)」の平均、最大値、最小値を集計してみます。

df_culc2 = df[['都道府県名', '元号', '人口(総数)']].groupby(by=['都道府県名', '元号']).agg('describe')
df_culc2.round(0)
人口(総数)
countmeanstdmin0.250.50.75max
都道府県名元号
三重県大正210884812716810692701078876108848110980861107692
平成618381272850517925141822238184804118566851866963
昭和12145622519497311574071345410148531815638131747311
京都府大正213467648431212871471316956134676413765731406382
平成626284251836226024602615163263284226423162647660
..............................
鳥取県平成660217717328573441593253610150614519615722
昭和1256592449776484390545030580582601188616024
鹿児島県大正214438884003014155821429735144388814580401472193
平成617476405968616481771717976176968617922161797824
昭和12174982616116015384661590966175688618278382044112
141 rows × 8 columns

小数点以下を切り捨てたことで見やすくなっていますが、桁区切り表示させることでより分かりやすくできます。

applymapメソッドとformatメソッドを使って3桁区切りにします。

df_culc2.applymap('{:,.0f}'.format)
人口(総数)
countmeanstdmin0.250.50.75max
都道府県名元号
三重県大正21,088,48127,1681,069,2701,078,8761,088,4811,098,0861,107,692
平成61,838,12728,5051,792,5141,822,2381,848,0411,856,6851,866,963
昭和121,456,225194,9731,157,4071,345,4101,485,3181,563,8131,747,311
京都府大正21,346,76484,3121,287,1471,316,9561,346,7641,376,5731,406,382
平成62,628,42518,3622,602,4602,615,1632,632,8422,6423162,647,660
..............................
鳥取県平成6602,17717,328573,441593,253610,150614,519615,722
昭和12565,92449,776484,390545,030580,582601,188616,024
鹿児島県大正21,443,88840,0301,415,5821,429,7351,443,8881,458,0401,472,193
平成61,747,64059,6861,648,1771,717,9761,769,6861,792,2161,797,824
昭和121,749,826161,1601,538,4661,590,9661,756,8861,827,8382,044,112
141 rows × 8 columns

【データを集計する | pivot_table】

groupbyメソッドではカラム(縦方向)でグルーピングして集計をしましたが、pivot_tableメソッドでは横方向にも項目を追加して集計することができます。

引数indexには縦方向に表示させたい項目、columnsには横方向に表示させたい項目を指定します。

引数valuesに集計するデータのカラムを指定します。

引数aggfuncには集計方法を指定します。

indexに「都道府県名」、columnsに「元号」を指定して、「人口(総数)」の平均を集計してみます。

df_pivot1 = df.pivot_table(index='都道府県名', columns='元号', values='人口(総数)', aggfunc='mean')
df_pivot1.round(0).head(10)
元号 大正 平成 昭和
都道府県名
三重県 1088481 1838127.0 1456225.0
京都府 1346764 2,628,425 2,020,190
佐賀県 679363 864,635 838,746
兵庫県 2378239 5,511,838 3,903,583
北海道 2428931 5,589,153 4,477,442
千葉県 1367706 5,962,486 2,776,920
和歌山県 768961 1037736.0 983590.0
埼玉県 1356997 6,936,328 3,039,185
大分県 887709 1,210,304 1,150,505
大阪府 2823674 8,809,791 5,759,113

複数のデータを集計する

複数データを同時に集計することができます。

indexに「都道府県名」、columnsに「元号」を指定して、「人口(総数)」、「人口(男)」、「人口(女)」人口の平均を集計してみます。

df_pivot2 = df.pivot_table(index='都道府県名', columns='元号', values=['人口(総数)', '人口(男)', '人口(女)'], aggfunc='mean')
df_pivot2.round(0).head(10)
人口(女)人口(男)人口(総数)
元号大正平成昭和大正平成昭和大正平成昭和
都道府県名
三重県553126944960753090535354893168703135108848118381271456225
京都府662642136009910282176841221268325991973134676426284252020190
佐賀県346270456442439106333092408192399640679363864635838746
兵庫県117086328615271983996120737626503101919587237823955118383903583
北海道115403429233722235757127489826657812241685242893155891534477442
千葉県6936012974638139994967410529878471376970136770659624862776920
和歌山県3868365471125074473821244906244761437689611037736983590
埼玉県6953903443448152351366160634928801515672135699769363283039185
大分県45070663877460120743700357153154929788770912103041150505
大阪府135413845171152870776146953642926762888337282367488097915759113

複数の集計方法を同時に実行する

引数aggfuncにリストで集計方法を指定することで、複数の集計方法を同時に実行することができます。

indexに「都道府県名」、columnsに「元号」を指定して、「人口(総数)」の平均、最大値、最小値を集計してみます。

df_pivot3 = df.pivot_table(index='都道府県名', columns='元号', values='人口(総数)', aggfunc=['mean', 'max', 'min'])
df_pivot3.round(0).head(10)
meanmaxmin
元号大正平成昭和大正平成昭和大正平成昭和
都道府県名
三重県108848118381271456225110769218669631747311106927017925141157407
京都府134676426284252020190140638226476602586574128714726024601552832
佐賀県679363864635838746684831884316973749673895832832686117
兵庫県237823955118383903583245467955906015278050230179954018772646301
北海道242893155891534477442249867956923215679439235918353817332812335
千葉県136770659624862776920139925762226665148163133615555554291470121
和歌山県768961103773698359078751110804351087206750411963579830748
埼玉県135699769363283039185139446172665345863678131953364053191459172
大分県88770912103041150505915136123694212771998602821166338945771
大阪府282367488097915759113305950288652458668095258784787345162800958

【さいごに】

今回はデータを集計する方法として「groupby」、「pivot_table」を紹介しました。

特に「pivot_table」はシンプルかつ非常に分かりやすいデータ分析手法です。

これを機に覚えてしまいましょう。

使用したCSVファイルやJupyter NotebookはGitHubに公開しています。
Jupyter Notebookは下記コマンドでダウンロードできるので、自由に使って是非練習してみてください。

$ curl https://raw.githubusercontent.com/nakachan-ing/python-references/master/Pandas/pandasでデータ集計する.ipynb -O
python-references/Pandas at master · nakachan-ing/python-references
Contribute to nakachan-ing/python-references development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました