Pandas 超入門3

本記事は Pandas 超入門2 の続きです。 Colaboratory での実行を想定しています。 準備はこちらを参照ください。

pandas

pandas とは、スプレッドシートのようなデータを読み込み、操作、整形、結合(マージ)する機能を備えたライブラリです。ここでは基本的な操作について述べるに留めます。より詳しく pandas について知りたい場合は 公式ドキュメント を参照ください。

まず、ライブラリをインポートします。

import pandas as pd

次にアンスコムのデータを読み込みます。

anscombe = pd.read_json('./sample_data/anscombe.json')

グループ演算

グループ演算とは、テーブルを指定したキーによって複数の部分に分割し、各分割部分に関数を適用し、その結果を結合して新しいデータを作成する演算のことを言います。

例えば、アンスコムのデータで、SeriesごとにYの値の合計値を取得したいとします。その場合、groupby関数を用いて次のように書きます。

anscombe.groupby('Series')['Y'].sum()
Series
I      82.50
II     82.51
III    82.50
IV     82.51
Name: Y, dtype: float64

一つのカラムに関してだけでなく、複数のカラムについての合計を出したい場合はカラムのリストを渡します。

anscombe.groupby('Series')[['X','Y']].sum()
	     X	Y
Series		
I	99	82.50
II	99	82.51
III	99	82.50
IV	99	82.51

要約統計量が欲しい場合はdescribe()関数を使うと得られます。

anscombe.groupby('Series')[['X','Y']].describe()
	     X	                                  Y
       count	mean	std	min	25%	50%	75%	max	count	mean	std	min	25%	50%	75%	max
Series																
I	11.0	9.0	3.316625	4.0	6.5	9.0	11.5	14.0	11.0	7.500000	2.032890	4.26	6.315	7.58	8.57	10.84
II	11.0	9.0	3.316625	4.0	6.5	9.0	11.5	14.0	11.0	7.500909	2.031657	3.10	6.695	8.14	8.95	9.26
III	11.0	9.0	3.316625	4.0	6.5	9.0	11.5	14.0	11.0	7.500000	2.030424	5.39	6.250	7.11	7.98	12.74
IV	11.0	9.0	3.316625	8.0	8.0	8.0	8.0	19.0	11.0	7.500909	2.030579	5.25	6.170	7.04	8.19	12.50

numpyで紹介した代表的な関数はすべて同じように使用できます。

マージ

マージとは複数のテーブルを1つに結合する作業のことを言います。外部データを例にマージの方法を紹介します。まずは外部データを読み込みましょう。読み込む外部データは1930年前後に行われた到達不能極(南極)調査データです。データは ここ から拝借しています。

まずは調査メンバーについてのテーブルです。

# 外部データの読み込み(調査メンバー)
person = pd.read_csv(
    'https://github.com/swcarpentry/sql-novice-survey/raw/gh-pages/data/person.csv',
    header=None,
    names=['ident', 'personal', 'family']
)
print(person)
      ident   personal    family
0      dyer    William      Dyer
1        pb      Frank   Pabodie
2      lake   Anderson      Lake
3       roe  Valentina   Roerich
4  danforth      Frank  Danforth

次に調査地点の名称と緯度経度のテーブルです。

# 外部データの読み込み(調査地点の名称と緯度経度)
site = pd.read_csv(
    'https://github.com/swcarpentry/sql-novice-survey/raw/gh-pages/data/site.csv',
    header=None,
    names=['name', 'lat', 'long']
)
print(site)
    name    lat    long
0   DR-1 -49.85 -128.57
1   DR-3 -47.15 -126.72
2  MSK-4 -48.87 -123.40

さらに調査地点名称と日付のテーブルです。

# 外部データの読み込み(調査地点名称と日付)
visit = pd.read_csv(
    'https://github.com/swcarpentry/sql-novice-survey/raw/gh-pages/data/visited.csv',
    header=None,
    names=['ident', 'site', 'dated']
)
print(visit)
   ident   site       dated
0    619   DR-1  1927-02-08
1    622   DR-1  1927-02-10
2    734   DR-3  1930-01-07
3    735   DR-3  1930-01-12
4    751   DR-3  1930-02-26
5    752   DR-3         NaN
6    837  MSK-4  1932-01-14
7    844   DR-1  1932-03-22

最後に調査結果のテーブルです。

# 外部データの読み込み(調査結果)
survey = pd.read_csv(
    'https://github.com/swcarpentry/sql-novice-survey/raw/gh-pages/data/survey.csv',
    header=None,
    names=['taken', 'person', 'quant', 'reading']
)
print(survey)
    taken person quant  reading
0     619   dyer   rad     9.82
1     619   dyer   sal     0.13
2     622   dyer   rad     7.80
3     622   dyer   sal     0.09
4     734     pb   rad     8.41
5     734   lake   sal     0.05
6     734     pb  temp   -21.50
7     735     pb   rad     7.22
8     735    NaN   sal     0.06
9     735    NaN  temp   -26.00
10    751     pb   rad     4.35
11    751     pb  temp   -18.50
12    751   lake   sal     0.10
13    752   lake   rad     2.19
14    752   lake   sal     0.09
15    752   lake  temp   -16.00
16    752    roe   sal    41.60
17    837   lake   rad     1.46
18    837   lake   sal     0.21
19    837    roe   sal    22.50
20    844    roe   rad    11.25

例えば、調査結果が誰に行われたものかという情報を見たいときは、調査結果(survey)と調査メンバー(person)をマージしたテーブルを用意する必要があるでしょう。マージするためには、merge関数を利用します。

<呼び出し元DataFrame>.merge(<マージするDataFrame>)

今回は survey を呼び出し元DataFrameとします。これはマージする際「左」と呼ばれます 。一方、person はマージするDataFrameとします。これは「右」と呼ばれます。さらにマージする際には左右それぞれどのカラムの値で紐付けを行うのかを指定する必要があります。この紐付けに使うカラムのことを「キー」と呼ばれます、キーの指定は、onパラメータを使うのですが、今回はsurvey(左)にあるpersonカラムと、person(右)にあるidentを紐付けに使うので、merge関数のなかでは、left_onパラメータとright_onパラメータでそれぞれキーを指定します。

print(survey.merge(person,left_on='person', right_on='ident'))
    taken person quant  reading ident   personal   family
0     619   dyer   rad     9.82  dyer    William     Dyer
1     619   dyer   sal     0.13  dyer    William     Dyer
2     622   dyer   rad     7.80  dyer    William     Dyer
3     622   dyer   sal     0.09  dyer    William     Dyer
4     734     pb   rad     8.41    pb      Frank  Pabodie
5     734     pb  temp   -21.50    pb      Frank  Pabodie
6     735     pb   rad     7.22    pb      Frank  Pabodie
7     751     pb   rad     4.35    pb      Frank  Pabodie
8     751     pb  temp   -18.50    pb      Frank  Pabodie
9     734   lake   sal     0.05  lake   Anderson     Lake
10    751   lake   sal     0.10  lake   Anderson     Lake
11    752   lake   rad     2.19  lake   Anderson     Lake
12    752   lake   sal     0.09  lake   Anderson     Lake
13    752   lake  temp   -16.00  lake   Anderson     Lake
14    837   lake   rad     1.46  lake   Anderson     Lake
15    837   lake   sal     0.21  lake   Anderson     Lake
16    752    roe   sal    41.60   roe  Valentina  Roerich
17    837    roe   sal    22.50   roe  Valentina  Roerich
18    844    roe   rad    11.25   roe  Valentina  Roerich

結果をみるともとのsurveyデータにあったtaken735となっているデータが一部なくなっていることがわかります。これは、マージの仕方によるものです。merge関数ではマージの仕方をhowというパラメータで指定することができ、指定しない場合はデフォルトでinnerが指定されます。howパラメータによるマージの仕方の指定とその説明は下の表のようになります。

howの指定説明
inner左右両方に存在するキーだけを残す
outer左右のキーをすべて残す
left左にあるキーのみを残す
right右にあるキーのみを残す

今回の例では左のキーにあるNaNが右のキーには含まれず、それがinnerというマージの仕方で落ちた言うことになります。もし、このデータも残すようなマージの仕方(「左にあるキーを残す」)をするのであれば、leftと指定することで達成できます。

# left join
print(survey.merge(person,left_on='person', right_on='ident', how='left'))
    taken person quant  reading ident   personal   family
0     619   dyer   rad     9.82  dyer    William     Dyer
1     619   dyer   sal     0.13  dyer    William     Dyer
2     622   dyer   rad     7.80  dyer    William     Dyer
3     622   dyer   sal     0.09  dyer    William     Dyer
4     734     pb   rad     8.41    pb      Frank  Pabodie
5     734   lake   sal     0.05  lake   Anderson     Lake
6     734     pb  temp   -21.50    pb      Frank  Pabodie
7     735     pb   rad     7.22    pb      Frank  Pabodie
8     735    NaN   sal     0.06   NaN        NaN      NaN
9     735    NaN  temp   -26.00   NaN        NaN      NaN
10    751     pb   rad     4.35    pb      Frank  Pabodie
11    751     pb  temp   -18.50    pb      Frank  Pabodie
12    751   lake   sal     0.10  lake   Anderson     Lake
13    752   lake   rad     2.19  lake   Anderson     Lake
14    752   lake   sal     0.09  lake   Anderson     Lake
15    752   lake  temp   -16.00  lake   Anderson     Lake
16    752    roe   sal    41.60   roe  Valentina  Roerich
17    837   lake   rad     1.46  lake   Anderson     Lake
18    837   lake   sal     0.21  lake   Anderson     Lake
19    837    roe   sal    22.50   roe  Valentina  Roerich
20    844    roe   rad    11.25   roe  Valentina  Roerich