1. pandas入門#

pandasは表形式のデータと時系列データを効率良く扱うために便利なPythonライブラリである. pandasは行列データを効率的に扱うNumPyをバックエンドに持っており,機械学習ライブラリとの相性も良い. そのため,Pythonを用いたデータ分析を行う際に非常に良く用いられる.

この文書では,データ分析の際に実用的に用いるpandasの機能のうち,最低限覚えておくべき内容をピックアップする.

1.1. はじめに - 表データとデータフレーム#

pandasで扱うデータは,以下のように行と列からなる表データである.

都道府県ID

都道府県名

2020年法定人口

県庁所在地

1

北海道

5224614

札幌市

2

青森県

1237984

青森市

3

岩手県

1210534

盛岡市

一般に表データはMicrosoftのExcelファイルで取り扱われることが多い. しかし,データ分析の世界では,比較的小さな表データは,特定のソフトウェアに依存しない(互換性の高い)CSV(comma-sepprated values)ファイル,もしくはTSV(tab-separated values)ファイルで保存/配布されることが多い.

CSVファイルは表の各項目の値をカンマ(,)で区切ったテキストデータである. CSVファイルの行が表の行に相当する. CSVファイルの1行目には,表の構造を示す項目名を並べることがある. CSVファイルの拡張子には.csvが用いられる.

以下は,上記都道府県に関する表データをCSVファイルとして保存したその中身の例である.

 都道府県ID,都道府県名,2020年法定人口,県庁所在地
 1,北海道,5224614,札幌市
 2,青森県,1237984,青森市
 3,岩手県,1210534,盛岡市
...

1行には表の項目(見出し)が,2行目以降には各都道府県に関するデータがカンマで区切られ定義されている. この表データをTSVファイルで保存する場合は,カンマではなくタブ記号(\t)でデータを区切る. TSVファイルの拡張子は.tsvである.

pandasライブラリでは,表形式のデータをデータフレーム(DataFrame) という形式に変換し,データの前処理や分析を行う. データフレームとは,Pythonで計算処理を効率的に行うための表データのようなものと思えば良い. 以下,pandasの扱い方について説明する.

1.2. ライブラリの準備#

pandasはPythonの標準ライブラリではない. お手元の計算環境にpandasライブラリがない場合は,以下のコマンドでpandasをインストールしよう.

pip install pandas

pandasをインストール後,以下のコードを実行してpandasライブラリを読み込む.

import pandas as pd

Jupyterを用いている場合は,セルに以下を書いて実行しよう.

try:
    import pandas as pd
except:
    !pip install pandas
    import pandas as pd

以下は,表示を見やすくするためのおまじないである.

# 警告文を非表示に
import warnings
warnings.filterwarnings('ignore')

1.3. データの読み込み#

1.3.1. CSV/TSVファイルを読み込む#

Pythonで表データを分析する場合,誰かが作成したCSV/TSVファイルをpandasライブラリで読み込むのが典型的なシナリオである. このURLタイタニック号の乗船客に関するCSVファイルがある. こちらをダウンロードしてpandasで読み込んでみよう. ダウンロードしたファイルはdataディレクトリにtitanic_train.csvという名前で保存したとする.

pandasで表データを読み込むにはread_table関数を用いる. 以下はdatasetディレクトリにあるtitanic_train.csvを読み込み,ファイルの中身をデータフレームに変換したものを変数dfに格納するコードである. 関数の1つ目の引数にはファイルの保存先を指定する. sepという引数では,読み込んだファイルに用いられている区切り文字を指定している. 今回読み込むファイルはCSVファイルなのでカンマ(,)を指定している. TSVファイルを読み込む場合はタブ文字(\t)を指定する.

df = pd.read_table('data/titanic_train.csv', sep=',')

変数dfを表示してみよう. Jupyterを用いている場合,下記コードを実行するとdfの中身(の一部)が表示される. データフレーム形式のデータが得られていることが分かる.

df
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
... ... ... ... ... ... ... ... ... ... ... ... ...
886 887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.0000 NaN S
887 888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.0000 B42 S
888 889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.4500 NaN S
889 890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.0000 C148 C
890 891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.7500 NaN Q

891 rows × 12 columns

先ほどはダウンロードしたファイルを読み込んだが,read_table関数はURLを指定することでファイルのダウンロードと読み込みを一括して行ってくれる. 先ほどのコードを以下に書き換えると,指定したURL上のファイルを読み込み,データフレームを作成する.

df = pd.read_table('https://raw.githubusercontent.com/hontolab-courses/ml-lecturenote/refs/heads/main/content/data/titanic_train.csv', sep=',')

read_table関数は引数に様々なオプションを指定できる(詳しくはドキュメントを参考). 代表的な引数は以下の通り:

  • sep: 区切り文字

  • header: 指定ファイルの中で見出し項目が格納された行番号(デフォルトは0)

  • encoding: ファイルの文字コード

  • index_col: インデックスをつけるために用いる列名

Note

インデックス

DataFrameオブジェクトにおけるインデックスとは,表中の行を識別するために各行につけられた固有の名前である. pandasでCSVファイルやTSVファイルをデータフレームとして読み込む際,インデックスを指定しない場合,行番号(先頭から数えて何番目の行かを表す数字)がインデックスとなる. インデックスが指定されていると,インデックスと行番号が同じにならないこともある.

例えば,こちらのURLで公開されている独立行政法人統計センター作成の教育用標準データセットSSDSE-基本素材(SSDSE-E)の表データを読み込んでみよう.

このデータはCSVファイルに格納されているが,文字コードとしてSHIFT-JISが用いられている. また,表の見出しは3行目で定義されており,4行目以降に実データが記述されている. このことを踏まえて,SSDSE-Eのデータをデータフレームとして読み込むコードは以下となる.

# CSVファイルの1行目をpandasではゼロ行目と読むので,3行目のデータを見出しとして指定する場合はheader=2となる
# 地域コードをインデックス名として指定
df = pd.read_table('https://www.nstac.go.jp/sys/files/SSDSE-E-2024.csv',
                   sep=',', header=2, encoding='shift-jis',
                   index_col='地域コード')

1.4. データの確認#

以下,上で読み込んだ独立行政法人統計センター作成の教育用標準データセットSSDSE-基本素材(SSDSE-E)の表データがデータフレームに変換の上,変数dfに格納されているとの前提で説明する.

1.4.1. 表の行数,列数の確認#

DataFrameオブジェクトのプロパティshapeにアクセスすると行数と列数のタプルが得られる.

df.shape
(48, 91)

1.4.2. 表の行数#

表データの行数だけを得たいときは,len関数を用いる(★Quiz Q2).

len(df)
48

1.4.3. 表の項目情報#

表データの項目名を取得したい場合は,DataFrameオブジェクトのプロパティcolumnsにアクセスする. columnsにアクセスすると,項目名のリストを得られる.

df.columns
Index(['都道府県', '総人口', '日本人人口', '15歳未満人口', '15〜64歳人口', '65歳以上人口', '外国人人口',
       '出生数', '合計特殊出生率', '死亡数', '転入者数(日本人移動者)', '転出者数(日本人移動者)', '一般世帯数',
       '一般世帯人員数', '単独世帯数', '婚姻件数', '離婚件数', '総面積(北方地域及び竹島を除く)', '可住地面積',
       '自然公園面積', '県内総生産額(平成27年基準)', '県民所得(平成27年基準)', '1人当たり県民所得(平成27年基準)',
       '事業所数(民営)', '事業所数(民営)(建設業)', '事業所数(民営)(製造業)', '事業所数(民営)(情報通信業)',
       '事業所数(民営)(卸売業、小売業)', '事業所数(民営)(宿泊業、飲食サービス業)', '事業所数(民営)(生活関連サービス業、娯楽業)',
       '事業所数(民営)(医療、福祉)', '従業者数(民営)', '従業者数(民営)(建設業)', '従業者数(民営)(製造業)',
       '従業者数(民営)(情報通信業)', '従業者数(民営)(卸売業、小売業)', '従業者数(民営)(宿泊業、飲食サービス業)',
       '従業者数(民営)(生活関連サービス業、娯楽業)', '従業者数(民営)(医療、福祉)', '農家数(販売農家)', '農家数(自給的農家)',
       '耕地面積', '旅館営業施設数(ホテルを含む)', '旅館営業施設客室数(ホテルを含む)', '幼稚園数', '幼稚園在園者数',
       '小学校数', '小学校児童数', '中学校数', '中学校生徒数', '高等学校数', '高等学校生徒数', '短期大学数', '大学数',
       '短期大学学生数', '大学学生数', '公民館数', '図書館数', '博物館数', '劇場、音楽堂等数', '社会体育施設数',
       '民間体育施設数', '映画館数', '一般旅券発行件数', '延べ宿泊者数', '外国人延べ宿泊者数', '総住宅数', '空き家数',
       '持ち家数', '一戸建住宅数', '1住宅当たり延べ面積', '総人口(非水洗化人口+水洗化人口)', '非水洗化人口',
       'ごみ総排出量(総量)', '1人1日当たりの排出量', 'ごみのリサイクル率', '小売店数', '飲食店数', '大型小売店数',
       '一般病院数', '一般診療所数', '歯科診療所数', '医師数', '歯科医師数', '薬剤師数', '保育所等数',
       '保育所等在所児数', '消費支出(二人以上の世帯)', '食料費(二人以上の世帯)', '住居費(二人以上の世帯)',
       '教養娯楽費(二人以上の世帯)'],
      dtype='object')

1.4.4. 基本統計量#

DataFrameオブジェクトのメソッドdescribeを用いると,表の各項目の基本統計量が得られる. 得られる基本統計量は以下の通り:

  • データ数

  • 平均

  • 標準偏差

  • 最小値,最大値

  • 中央値

  • 第1四分位数,第3四分位数

df.describe()
総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 転入者数(日本人移動者) ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
count 4.800000e+01 4.800000e+01 4.800000e+01 4.800000e+01 4.800000e+01 4.800000e+01 48.000000 48.000000 4.800000e+01 4.800000e+01 ... 48.000000 48.000000 48.000000 48.000000 48.000000 4.800000e+01 48.000000 48.000000 48.00000 48.000000
mean 5.206104e+06 5.084646e+06 6.043125e+05 3.092000e+06 1.509812e+06 1.001025e+05 33817.354167 1.397708 5.997579e+04 9.397342e+04 ... 2829.125000 14150.958333 4476.791667 13415.916667 1249.750000 1.101331e+05 289656.083333 76615.958333 19231.12500 25987.687500
std 1.786588e+07 1.744375e+07 2.072707e+06 1.063209e+07 5.164664e+06 3.497592e+05 116144.047847 0.145225 2.051223e+05 3.259851e+05 ... 9765.277128 48665.779507 15458.270437 46353.143907 4278.561169 3.769878e+05 18982.531256 5518.803196 4783.81712 3771.185339
min 5.440000e+05 5.390000e+05 6.600000e+04 2.980000e+05 1.800000e+05 3.651000e+03 3708.000000 1.080000 7.605000e+03 7.967000e+03 ... 254.000000 1871.000000 369.000000 1229.000000 185.000000 1.640300e+04 245054.000000 67889.000000 6220.00000 17601.000000
25% 1.049250e+06 1.041250e+06 1.205000e+05 5.690000e+05 3.500000e+05 9.606750e+03 6409.750000 1.300000 1.366800e+04 1.544575e+04 ... 489.500000 2867.250000 738.000000 2424.000000 298.750000 2.488425e+04 276968.250000 72335.500000 16401.00000 22929.250000
50% 1.640500e+06 1.619500e+06 2.025000e+05 9.135000e+05 5.270000e+05 1.567700e+04 11108.000000 1.400000 2.180900e+04 2.477100e+04 ... 804.000000 4348.500000 1277.500000 3524.000000 447.500000 3.953300e+04 289323.000000 75822.500000 19698.50000 25953.500000
75% 2.780000e+06 2.722750e+06 3.257500e+05 1.609250e+06 8.355000e+05 5.268950e+04 17035.500000 1.467500 3.228400e+04 4.818850e+04 ... 1413.000000 7921.500000 2151.000000 6954.000000 684.500000 5.955550e+04 301817.000000 80910.250000 22282.00000 28304.500000
max 1.249470e+08 1.220310e+08 1.450300e+07 7.420800e+07 3.623600e+07 2.402460e+06 811622.000000 1.800000 1.439856e+06 2.255362e+06 ... 67899.000000 339623.000000 107443.000000 321982.000000 29994.000000 2.643196e+06 324793.000000 87973.000000 30323.00000 35050.000000

8 rows × 90 columns

1.5. データフレームへのアクセス#

1.5.1. 先頭・末尾のレコード(行)の取得#

DataFrameオブジェクトのメソッドheadは,データフレームの先頭\(N\)件のレコードを返す. 引数に何も指定しないと5件返す.

df.head()
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R00000 全国 124947000 122031000 14503000 74208000 36236000 2402460 811622 1.30 1439856 ... 67899 339623 107443 321982 29994 2643196 290865 77474 18645 26642
R01000 北海道 5140000 5098000 530000 2924000 1686000 34321 28762 1.20 69023 ... 2818 13731 4418 11802 1075 76885 277737 73037 24873 27234
R02000 青森県 1204000 1198000 123000 663000 419000 5409 6513 1.31 18785 ... 505 2773 735 2345 472 30738 249660 73725 10541 20068
R03000 岩手県 1181000 1173000 125000 648000 408000 6937 6472 1.30 17631 ... 557 2700 1016 2536 393 28580 285815 77251 18814 25733
R04000 宮城県 2280000 2256000 258000 1363000 659000 19453 13761 1.15 25897 ... 1051 5950 1896 5502 506 40519 287781 78589 22951 26516

5 rows × 91 columns

DataFrameオブジェクトのメソッドtailは,データフレームの末尾\(N\)件のレコードを返す. 引数に何も指定しないと5件返す(★Quiz Q1).

df.tail()
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R43000 熊本県 1718000 1699000 223000 943000 552000 14591 12670 1.59 22093 ... 835 5415 1377 4036 623 52158 281836 70132 30323 24428
R44000 大分県 1107000 1092000 131000 600000 376000 10168 7327 1.54 15104 ... 530 3370 740 2317 335 26578 298060 75218 18820 28260
R45000 宮崎県 1052000 1044000 136000 565000 352000 6474 7590 1.64 14520 ... 493 2879 731 2272 420 30732 271613 70162 15433 21950
R46000 鹿児島県 1563000 1550000 201000 838000 523000 10037 11618 1.65 21979 ... 795 4653 1352 3266 582 40357 279101 70070 20822 22440
R47000 沖縄県 1468000 1446000 240000 884000 344000 18157 14535 1.80 13582 ... 607 3887 885 2432 614 57108 251735 68318 25189 18429

5 rows × 91 columns

1.5.2. 射影#

表データから指定した列のみに注目してデータを抽出する操作,関係データベースの分野では射影と呼ぶ.

pandasのDataFrameで射影を行う方法は2種類ある. 1つ目は注目したい列項目名をドット(.)で指定する方法である. 以下は,データフレームdfから列「総人口」にあるデータを抽出するコードである.

df.総人口
地域コード
R00000    124947000
R01000      5140000
R02000      1204000
R03000      1181000
R04000      2280000
            ...    
R43000      1718000
R44000      1107000
R45000      1052000
R46000      1563000
R47000      1468000
Name: 総人口, Length: 48, dtype: int64

もう1つの射影方法は,中括弧の中で列項目名を指定する方法である. この方法では,注目したい列名を文字列もしくは文字列のリストで指定する. 以下は,データフレームdfから列「総人口」にあるデータを抽出するコードである.

df['総人口']
地域コード
R00000    124947000
R01000      5140000
R02000      1204000
R03000      1181000
R04000      2280000
            ...    
R43000      1718000
R44000      1107000
R45000      1052000
R46000      1563000
R47000      1468000
Name: 総人口, Length: 48, dtype: int64

ドットを用いる方法は簡便であるが,列項目を複数指定して射影できない. 中括弧を用いる射影方法では,中括弧の中に文字列のリストを与えることで,複数の列項目に注目してデータを抽出できる. 以下は,データフレームdfから「都道府県」「総人口」の列のデータを抽出するコードである(★Quiz Q3).

target_columns = ['都道府県', '総人口']
df[target_columns]

# 以下のように書いても問題ない
# df[['都道府県', '総人口']]
都道府県 総人口
地域コード
R00000 全国 124947000
R01000 北海道 5140000
R02000 青森県 1204000
R03000 岩手県 1181000
R04000 宮城県 2280000
... ... ...
R43000 熊本県 1718000
R44000 大分県 1107000
R45000 宮崎県 1052000
R46000 鹿児島県 1563000
R47000 沖縄県 1468000

48 rows × 2 columns

1.5.3. データフレームに対する四則演算#

pandasのDataFrameオブジェクトから任意の列を射影した後,スカラーの四則演算を適用すると,射影した列データ全体に演算が適用される. 例えば,以下はデータフレームdf総人口列の各値に100を加算するコード例である.

# 総人口列の各値に100が加算された列が返る
df.総人口 + 100
地域コード
R00000    124947100
R01000      5140100
R02000      1204100
R03000      1181100
R04000      2280100
            ...    
R43000      1718100
R44000      1107100
R45000      1052100
R46000      1563100
R47000      1468100
Name: 総人口, Length: 48, dtype: int64

列と列の長さ(要素数)が同じなら,列同士の四則演算を行うことができる. 2つの列同士の四則演算を行うと,双方の列の各行の値を四則演算した結果の列が返る.

以下は,データフレームdf日本人人口列の値を総人口列の値で割る(つまり,日本人の割合を求める)コード例である.

df['日本人人口'] / df['総人口']
地域コード
R00000    0.976662
R01000    0.991829
R02000    0.995017
R03000    0.993226
R04000    0.989474
            ...   
R43000    0.988941
R44000    0.986450
R45000    0.992395
R46000    0.991683
R47000    0.985014
Length: 48, dtype: float64

1.5.4. 任意の行にあるレコードの取得#

df[i:j]と書くと,データフレームdfi件目(ゼロを起点)からj-1件目のレコードを取得できる. 以下はデータフレームdfの2件目から4件目まで(5件目は含まれない)のレコードを取得するコードである.

df[2:5]
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R02000 青森県 1204000 1198000 123000 663000 419000 5409 6513 1.31 18785 ... 505 2773 735 2345 472 30738 249660 73725 10541 20068
R03000 岩手県 1181000 1173000 125000 648000 408000 6937 6472 1.30 17631 ... 557 2700 1016 2536 393 28580 285815 77251 18814 25733
R04000 宮城県 2280000 2256000 258000 1363000 659000 19453 13761 1.15 25897 ... 1051 5950 1896 5502 506 40519 287781 78589 22951 26516

3 rows × 91 columns

DataFrameオブジェクトのlocilocメソッドを用いると,任意の行にある任意の列の値を取得することができる.

  • locメソッドは任意の行(インデックス名),列

  • ilocメソッドは任意の行番号,列番号

値を取得するという違いがある.

locメソッドを用いると,行名,列名でレコードを取得できる. 以下はデータフレームdfのインデックス名が任意の値をもつレコード(つまり全てのレコード)について,「都道府県」「総人口」の列の値だけ抽出(射影)するコードである. ここで,コロン(”)はすべてを意味する.

target_columns = ['都道府県', '総人口']
df.loc[:, target_columns]
都道府県 総人口
地域コード
R00000 全国 124947000
R01000 北海道 5140000
R02000 青森県 1204000
R03000 岩手県 1181000
R04000 宮城県 2280000
... ... ...
R43000 熊本県 1718000
R44000 大分県 1107000
R45000 宮崎県 1052000
R46000 鹿児島県 1563000
R47000 沖縄県 1468000

48 rows × 2 columns

上記コードは,以下と同じ(射影後に取得行を絞る).

target_columns = ['都道府県', '総人口']
df[target_columns]
都道府県 総人口
地域コード
R00000 全国 124947000
R01000 北海道 5140000
R02000 青森県 1204000
R03000 岩手県 1181000
R04000 宮城県 2280000
... ... ...
R43000 熊本県 1718000
R44000 大分県 1107000
R45000 宮崎県 1052000
R46000 鹿児島県 1563000
R47000 沖縄県 1468000

48 rows × 2 columns

以下のようにlocメソッドの引数を指定すると,インデックス名と列名の両方でDataFrameオブジェクトを絞り込むことができる.

target_columns = ['都道府県', '総人口']
target_indices = ['R13000', 'R26000', 'R27000']
df.loc[target_indices, target_columns]

# 上記は以下のようにも書ける
# df.loc[['都道府県', '総人口'], ['R13000', 'R26000', 'R27000']]
都道府県 総人口
地域コード
R13000 東京都 14038000
R26000 京都府 2550000
R27000 大阪府 8782000

ilocメソッドを用いると,行番号,列番号でレコードを取得できる. 以下はデータフレームdfの行番号が2から4までのレコードについて,列番号が0から3までの列の値を抽出(射影)するコードである.

# データフレーム`df`の2件目から4件目(5件目未満)のレコードについて,
# 列番号が0から3までの列(つまり,「都道府県」「総人口」「日本人人口」)の列の値を抽出(射影)する
df.iloc[2:5, 0:3]
都道府県 総人口 日本人人口
地域コード
R02000 青森県 1204000 1198000
R03000 岩手県 1181000 1173000
R04000 宮城県 2280000 2256000

上の例では2件目から4件目までのように連続するレコードを取得していたが,ilocメソッドでは具体的なレコードの行番号をリストで指定してレコードを取得することもできる. 以下は,データフレームdfの1件目と11件目と21件目のレコードを抽出(射影)するコードである.

target_rows = [1, 11, 21]
df.iloc[target_rows, :]

# 以下のように書いても問題ない
# df.iloc[[1, 11, 21], :]
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R01000 北海道 5140000 5098000 530000 2924000 1686000 34321 28762 1.20 69023 ... 2818 13731 4418 11802 1075 76885 277737 73037 24873 27234
R11000 埼玉県 7337000 7136000 847000 4483000 2007000 161439 45424 1.22 75164 ... 3550 13604 5575 16370 1474 123008 324793 87922 21820 35050
R21000 岐阜県 1946000 1888000 231000 1111000 604000 48979 11730 1.40 24126 ... 959 4580 1735 4060 415 38709 313314 77357 13720 27226

3 rows × 91 columns

1.5.5. 絞り込み#

DataFrameオブジェクトから特定の条件を満たすレコードのみを取得するには2種類の方法がある:

  • 中括弧の中で条件を指定する方法

  • queryメソッドを使用する方法

データフレームdfにあるレコードの中で,「総人口」の値が700万以上になるものだけを抽出する例を考えてみよう. 中括弧の中で条件を指定してデータフレームにアクセスすると,条件にマッチするレコードだけが絞り込まれる. 条件指定には射影を用いる.

df[df['総人口'] >= 7000000]

# ドット表現を用いて条件を指定することも可能
# df[df.総人口 >= 7000000]
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R00000 全国 124947000 122031000 14503000 74208000 36236000 2402460 811622 1.30 1439856 ... 67899 339623 107443 321982 29994 2643196 290865 77474 18645 26642
R11000 埼玉県 7337000 7136000 847000 4483000 2007000 161439 45424 1.22 75164 ... 3550 13604 5575 16370 1474 123008 324793 87922 21820 35050
R13000 東京都 14038000 13443000 1535000 9301000 3202000 483372 95404 1.08 127649 ... 10678 48072 17245 52842 3523 290125 321633 87973 29988 33099
R14000 神奈川県 9232000 8991000 1053000 5797000 2383000 195535 58836 1.22 89701 ... 4984 21377 7605 23872 2012 165014 301379 85076 23065 29394
R23000 愛知県 7495000 7228000 948000 4628000 1920000 231369 53918 1.41 73769 ... 3718 17842 6159 16003 1558 148009 319344 79757 22575 30894
R27000 大阪府 8782000 8524000 1002000 5349000 2432000 208681 59780 1.27 97282 ... 5442 26431 8184 27297 1573 172365 265161 80890 18350 25978

6 rows × 91 columns

Note

df.総人口 >= 7000000 を実行すると何が返ってくるのか?

実行してみると分かるが,dfの各レコードの総人口が700万以上かそうでないかをTrueFalseで表したpandas.Series(リストのようなもの)が返ってくる. 返ってくるpandas.Seriesでは,nつ目の要素がdfのn番目のレコードがTrueFalseを表している. pandasのDataFrameオブジェクトは中括弧の中にTrue/Falseのリスト(もしくはpandas.Series)を入れると,値がTrueのレコードだけをDataFrameオブジェクトから抽出して返す. この振る舞いを利用して,pandasではレコードの絞り込みを行うのである.

同じことをDataFrameオブジェクトのqueryメソッドを使って書くと,以下のようになる(★Quiz Q4).

df.query('総人口 >= 7000000')
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R00000 全国 124947000 122031000 14503000 74208000 36236000 2402460 811622 1.30 1439856 ... 67899 339623 107443 321982 29994 2643196 290865 77474 18645 26642
R11000 埼玉県 7337000 7136000 847000 4483000 2007000 161439 45424 1.22 75164 ... 3550 13604 5575 16370 1474 123008 324793 87922 21820 35050
R13000 東京都 14038000 13443000 1535000 9301000 3202000 483372 95404 1.08 127649 ... 10678 48072 17245 52842 3523 290125 321633 87973 29988 33099
R14000 神奈川県 9232000 8991000 1053000 5797000 2383000 195535 58836 1.22 89701 ... 4984 21377 7605 23872 2012 165014 301379 85076 23065 29394
R23000 愛知県 7495000 7228000 948000 4628000 1920000 231369 53918 1.41 73769 ... 3718 17842 6159 16003 1558 148009 319344 79757 22575 30894
R27000 大阪府 8782000 8524000 1002000 5349000 2432000 208681 59780 1.27 97282 ... 5442 26431 8184 27297 1573 172365 265161 80890 18350 25978

6 rows × 91 columns

絞り込み条件は複数書くこともできる. 以下はAND条件の例.AND条件は&で繋ぐ.なお,1つ1つの条件は丸括弧で囲む.

# 総人口が700万人以上かつ都道府県名が「全国」でないレコードをすべて抽出
df[(df.総人口 >= 7000000) & (df.都道府県 != '全国')]

# queryメソッドを使うと,以下のように書ける
df.query('総人口 >= 7000000 & 都道府県 != "全国"')
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R11000 埼玉県 7337000 7136000 847000 4483000 2007000 161439 45424 1.22 75164 ... 3550 13604 5575 16370 1474 123008 324793 87922 21820 35050
R13000 東京都 14038000 13443000 1535000 9301000 3202000 483372 95404 1.08 127649 ... 10678 48072 17245 52842 3523 290125 321633 87973 29988 33099
R14000 神奈川県 9232000 8991000 1053000 5797000 2383000 195535 58836 1.22 89701 ... 4984 21377 7605 23872 2012 165014 301379 85076 23065 29394
R23000 愛知県 7495000 7228000 948000 4628000 1920000 231369 53918 1.41 73769 ... 3718 17842 6159 16003 1558 148009 319344 79757 22575 30894
R27000 大阪府 8782000 8524000 1002000 5349000 2432000 208681 59780 1.27 97282 ... 5442 26431 8184 27297 1573 172365 265161 80890 18350 25978

5 rows × 91 columns

以下はOR条件の例.OR条件は|(パイプ)で繋ぐ. 条件が増えると,中括弧で条件を指定する方法は見にくくなる. 条件が多い場合は,queryメソッドを使った方がコードの可読性を高められる(★Quiz Q5).

# 合計特殊出生率が1.8以上もしくは1.1未満のレコードをすべて抽出
df[(df.合計特殊出生率 >= 1.8) | (df.合計特殊出生率 < 1.1)]

# queryメソッドを使うと,以下のように書ける
# df.query('合計特殊出生率 >= 1.8 | 合計特殊出生率 < 1.1')
都道府県 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R13000 東京都 14038000 13443000 1535000 9301000 3202000 483372 95404 1.08 127649 ... 10678 48072 17245 52842 3523 290125 321633 87973 29988 33099
R47000 沖縄県 1468000 1446000 240000 884000 344000 18157 14535 1.80 13582 ... 607 3887 885 2432 614 57108 251735 68318 25189 18429

2 rows × 91 columns

1.6. データフレームの保存#

データフレームの中身をCSV/TSVファイルに保存するにはDataFrameオブジェクトのto_csvメソッドを用いる. 以下,データフレームdfdataディレクトリにCSVファイルとして保存するコード例.

df.to_csv('data/SSDSE-E-2024.csv')

to_csvメソッドは指定がなければ,データフレームをCSVファイルとして保存する. TSVファイルとして保存したい場合は,以下のように引数sep\tを指定する. ファイル名の拡張子も.tsvとしておこう.

df.to_csv('data/SSDSE-E-2024.tsv', sep='\t')

見出しやインデックス(データフレームが割り振った索引名)を保存するかはheader引数およびindex引数で指定する. 双方の引数ともにデフォルトはTrue(保存する).

# 以下の場合,見出しはCSVファイルに保存し,インデックスは保存しない
df.to_csv('data/SSDSE-E-2024.csv', header=True, index=False)

1.7. 前処理#

1.7.1. 列名の変更#

列名の変更はDataFrameオブジェクトのrenameメソッドで行う. renameメソッドののcolumns引数に{'変更前の列名': '変更後の列名'}形式の辞書を与えると,列名を変更できる. renameメソッドは列名変更後のDataFrameオブジェクトを返す.

df.rename(columns={'都道府県': 'prefecture'})
prefecture 総人口 日本人人口 15歳未満人口 15〜64歳人口 65歳以上人口 外国人人口 出生数 合計特殊出生率 死亡数 ... 歯科診療所数 医師数 歯科医師数 薬剤師数 保育所等数 保育所等在所児数 消費支出(二人以上の世帯) 食料費(二人以上の世帯) 住居費(二人以上の世帯) 教養娯楽費(二人以上の世帯)
地域コード
R00000 全国 124947000 122031000 14503000 74208000 36236000 2402460 811622 1.30 1439856 ... 67899 339623 107443 321982 29994 2643196 290865 77474 18645 26642
R01000 北海道 5140000 5098000 530000 2924000 1686000 34321 28762 1.20 69023 ... 2818 13731 4418 11802 1075 76885 277737 73037 24873 27234
R02000 青森県 1204000 1198000 123000 663000 419000 5409 6513 1.31 18785 ... 505 2773 735 2345 472 30738 249660 73725 10541 20068
R03000 岩手県 1181000 1173000 125000 648000 408000 6937 6472 1.30 17631 ... 557 2700 1016 2536 393 28580 285815 77251 18814 25733
R04000 宮城県 2280000 2256000 258000 1363000 659000 19453 13761 1.15 25897 ... 1051 5950 1896 5502 506 40519 287781 78589 22951 26516
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
R43000 熊本県 1718000 1699000 223000 943000 552000 14591 12670 1.59 22093 ... 835 5415 1377 4036 623 52158 281836 70132 30323 24428
R44000 大分県 1107000 1092000 131000 600000 376000 10168 7327 1.54 15104 ... 530 3370 740 2317 335 26578 298060 75218 18820 28260
R45000 宮崎県 1052000 1044000 136000 565000 352000 6474 7590 1.64 14520 ... 493 2879 731 2272 420 30732 271613 70162 15433 21950
R46000 鹿児島県 1563000 1550000 201000 838000 523000 10037 11618 1.65 21979 ... 795 4653 1352 3266 582 40357 279101 70070 20822 22440
R47000 沖縄県 1468000 1446000 240000 884000 344000 18157 14535 1.80 13582 ... 607 3887 885 2432 614 57108 251735 68318 25189 18429

48 rows × 91 columns

1.7.2. 新しい列の追加#

DataFrameオブジェクトに新しい列を追加する最も単純な方法は,中括弧で新規で追加する列に「アクセス」して値を代入する方法である. 以下は,データフレームdf生産年齢人口率という列名を追加して,15〜64歳人口列の値を総人口列の値で割った値を代入するコード例である.

df['生産年齢人口率'] = df['15〜64歳人口'] / df['総人口']

DataFrameオブジェクトに新しい列を追加するもう1つの方法はassignメソッドを用いる方法である. assignメソッドを用いると,複数の列を同時に追加できる.

以下は,データフレームdf生産年齢人口率に加えて,医師数列,歯科医師数列,薬剤師数列の値の合計値を格納した医療従事者数という列を追加するコード例である. なお,assignメソッドは返り値として列を追加後のDataFrameオブジェクトを返すことに注意(元のDataFrameオブジェクトを変更しない). また,assignメソッドを使用するときは,代入先の列名はクオーツ(’)で包まない(文字列リテラルにする)ことに注意(★Quiz Q6★Quiz Q7).

df = df.assign(
    生産年齢人口率 = df['15〜64歳人口'] / df['総人口'],
    医療従事者数 = df['医師数'] + df['歯科医師数'] + df['薬剤師数']
)

1.7.3. NumPy行列の取得#

DataFrameオブジェクトからNumPy形式の(数値)行列を取り出すには,DataFrameオブジェクトのvaluesメソッドを用いる. 以下は,データフレームdfから総人口日本人人口外国人人口を抜き出して,NumPy行列(ndarray)に変換するコード例である.

target_columns = ['総人口', '日本人人口', '外国人人口']
df[target_columns].values
array([[124947000, 122031000,   2402460],
       [  5140000,   5098000,     34321],
       [  1204000,   1198000,      5409],
       [  1181000,   1173000,      6937],
       [  2280000,   2256000,     19453],
       [   930000,    926000,      3651],
       [  1041000,   1033000,      7149],
       [  1790000,   1776000,     12868],
       [  2840000,   2767000,     57819],
       [  1909000,   1865000,     37408],
       [  1913000,   1850000,     53432],
       [  7337000,   7136000,    161439],
       [  6266000,   6100000,    142177],
       [ 14038000,  13443000,    483372],
       [  9232000,   8991000,    195535],
       [  2153000,   2136000,     15028],
       [  1017000,    998000,     16326],
       [  1118000,   1102000,     13685],
       [   753000,    738000,     13796],
       [   802000,    784000,     13993],
       [  2020000,   1984000,     31491],
       [  1946000,   1888000,     48979],
       [  3582000,   3484000,     86046],
       [  7495000,   7228000,    231369],
       [  1742000,   1689000,     44721],
       [  1409000,   1373000,     28704],
       [  2550000,   2485000,     52442],
       [  8782000,   8524000,    208681],
       [  5402000,   5287000,     87280],
       [  1306000,   1291000,     11505],
       [   903000,    896000,      6029],
       [   544000,    539000,      4310],
       [   658000,    648000,      8230],
       [  1862000,   1832000,     25116],
       [  2760000,   2708000,     47733],
       [  1313000,   1297000,     14378],
       [   704000,    698000,      5033],
       [   934000,    920000,     10854],
       [  1306000,   1294000,     11159],
       [   676000,    671000,      4220],
       [  5116000,   5030000,     66699],
       [   801000,    793000,      5940],
       [  1283000,   1272000,      8316],
       [  1718000,   1699000,     14591],
       [  1107000,   1092000,     10168],
       [  1052000,   1044000,      6474],
       [  1563000,   1550000,     10037],
       [  1468000,   1446000,     18157]])

1.8. クイズ#

以下のクイズの回答にGoogle Colaboratoryを使いたい方はコチラをクリック.

1.8.1. Q1: データの読み込み#

pokemonDataは,ポケットモンスターシリーズに登場するポケモンの能力値をまとめたデータセットである. コチラのURLからCSVファイルをダウンロードし,その内容をpandasデータフレームに変換して変数pokemon_dfに代入しなさい. さらに,pokemon_dfの中身を確認しなさい.

1.8.2. Q2: データの確認#

データフレームpokemon_dfで取り扱われているポケモンの数(行数)および列数を調べなさい.

1.8.3. Q3: HP, 攻撃力, 防御力#

データフレームpokemon_dfで扱われているポケモンのHP,攻撃力(Attack),防御力(Defense)の平均値を調べなさい.

1.8.4. Q4: 第9世代#

データフレームpokemon_dfの中で,第9世代(スカーレット・ヴァイオレット)のポケモンの情報を表示しなさい.

1.8.5. Q5: ゴーストタイプ#

データフレームpokemon_dfの中で「ゴースト(Ghost)」タイプのポケモンの情報を表示しなさい.

1.8.6. Q6: 偏差値#

データフレームpokemon_dfの情報によると,Total値の平均値は443.1,標準偏差は121.2である. この値を用いてデータフレームpokemon_df中の各ポケモンのTotal値に関する偏差値を算出しなさい. また,計算した偏差値をpokemon_dfの列Total_Z_scoreに格納しなさい.

なお,\(x\)の平均値を\(\mu\),標準偏差を\(\sigma\)としたとき,\(x\)の偏差値\(z\)は以下の式で計算できる:

\[ z = \frac{x - \mu}{\sigma} \times 10 + 50 \]

1.8.7. Q7: データフレームの保存#

Totalの偏差値に関する列を追加したデータフレームpokemon_dfをTSVファイルとして保存しなさい. また,保存したTSVファイルをテキストエディタやExcelなどを用いて確認しなさい. なお,TSVファイル名はpokemon.tsvとし,見出し(列名)をファイル内に含めるようにすること.