7-1. pandasライブラリ

pandasライブラリについて説明します。

参考

pandasライブラリにはデータ分析作業を支援するためのモジュールが含まれています。以下では、pandasライブラリのモジュールの基本的な使い方について説明します。

pandasライブラリを使用するには、まず pandas モジュールをインポートします。慣例として、同モジュールを pd と別名をつけてコードの中で使用します。データの生成に用いるため、ここでは numpy モジュールも併せてインポートします。

[1]:
import pandas as pd
import numpy as np

シリーズとデータフレーム

pandas モジュールは、リスト、配列や辞書などのデータをシリーズ (Series) あるいはデータフレーム (DataFrame) のオブジェクトとして保持します。シリーズは列、データフレームは複数の列で構成されます。シリーズやデータフレームの行はインデックス index で管理され、インデックスには 0 から始まる番号、または任意のラベルが付けられています。インデックスが番号の場合は、シリーズやデータフレームはそれぞれNumPyの配列、2次元配列とみなすことができます。また、インデックスがラベルの場合は、ラベルをキー、各行を値とした辞書としてシリーズやデータフレームをみなすことができます。

シリーズ (Series) の作成

シリーズのオブジェクトは、以下のように、リスト、配列や辞書から作成することができます。

[2]:
# リストからシリーズの作成
s1 = pd.Series([0,1,2])
print(s1)

# 配列からシリーズの作成
s2 = pd.Series(np.random.rand(3))
print(s2)

# 辞書からシリーズの作成
s3 = pd.Series({0:'boo',1:'foo',2:'woo'})
print(s3)
0    0
1    1
2    2
dtype: int64
0    0.714490
1    0.592449
2    0.976355
dtype: float64
0    boo
1    foo
2    woo
dtype: object

以下では、シリーズ(列)より一般的なデータフレームの操作と機能について説明していきますが、データフレームオブジェクトの多くの操作や機能はシリーズオブジェクトにも適用できます。

データフレーム (DataFrame) の作成

データフレームのオブジェクトは、以下のように、リスト、配列や辞書から作成することができます。行のラベルは、DataFrameindex 引数で指定できますが、以下のデータフレーム作成の例、d2, d3、 では同インデックスを省略しているため、0 から始まるインデックス番号がラベルとして行に自動的に付けられます。列のラベルは columns 引数で指定します。辞書からデータフレームを作成する際は、columns 引数で列の順番を指定することになります。

[3]:
# 多次元リストからデータフレームの作成
d1 = pd.DataFrame([[0,1,2],[3,4,5],[6,7,8],[9,10,11]], index=[10,11,12,13], columns=['c1','c2','c3'])
print(d1)

# 多次元配列からデータフレームの作成
d2 = pd.DataFrame(np.random.rand(12).reshape(4,3), columns=['c1','c2','c3'])
print(d2)

# 辞書からデータフレームの作成
d3 = pd.DataFrame({'Initial':['B','F','W'], 'Name':['boo', 'foo', 'woo']}, columns=['Name','Initial'])
print(d3)
    c1  c2  c3
10   0   1   2
11   3   4   5
12   6   7   8
13   9  10  11
         c1        c2        c3
0  0.633429  0.264302  0.467160
1  0.656182  0.799303  0.058796
2  0.105300  0.205385  0.570039
3  0.815636  0.074122  0.085846
  Name Initial
0  boo       B
1  foo       F
2  woo       W

CSVファイルからのデータフレームの作成

pandas モジュールの read_csv() 関数を用いて、以下のようにCSVファイルを読み込んで、データフレームのオブジェクトを作成することができます。read_csv() 関数の encoding 引数にはファイルの文字コードを指定します。CSVファイル iris.csv には、以下のようにアヤメの種類 (species) と花弁 (petal)・がく片 (sepal) の長さ (length) と幅 (width) のデータが含まれています。

sepal_length, sepal_width, petal_length, petal_width, species
5.1, 3.5, 1.4, 0.2, setosa
4.9, 3.0, 1.4, 0.2, setosa
4.7, 3.2, 1.3, 0.2, setosa
...

head() メソッドを使うとデータフレームの先頭の複数行を表示させることができます。引数には表示させたい行数を指定し、行数を指定しない場合は、5行分のデータが表示されます。

[4]:
# CSVファイルの読み込み
iris_d = pd.read_csv('iris.csv')

# 先頭10行のデータを表示
iris_d.head(10)
[4]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
5 5.4 3.9 1.7 0.4 setosa
6 4.6 3.4 1.4 0.3 setosa
7 5.0 3.4 1.5 0.2 setosa
8 4.4 2.9 1.4 0.2 setosa
9 4.9 3.1 1.5 0.1 setosa

データフレームオブジェクトの index 属性により、データフレームのインデックスの情報が確認できます。len() 関数を用いると、データフレームの行数が取得できます。

[5]:
print(iris_d.index) #インデックスの情報
len(iris_d.index) #インデックスの長さ
RangeIndex(start=0, stop=150, step=1)
[5]:
150

データの参照

シリーズやデータフレームでは、行の位置(行は 0 から始まります)をスライスとして指定することで任意の行を抽出することができます。

[6]:
# データフレームの先頭5行のデータ
iris_d[:5]
[6]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
[7]:
# データフレームの終端5行のデータ
iris_d[-5:]
[7]:
sepal_length sepal_width petal_length petal_width species
145 6.7 3.0 5.2 2.3 virginica
146 6.3 2.5 5.0 1.9 virginica
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica

データフレームから任意の列を抽出するには、DataFrame.列名 のように、データフレームオブジェクトに . で列名をつなげることで、その列を指定してシリーズオブジェクトとして抽出することができます。なお、列名を文字列として、DataFrame['列名'] のように添字指定しても同様です。

[8]:
# データフレームの'species'の列の先頭10行のデータ
iris_d['species'].head(10)
[8]:
0    setosa
1    setosa
2    setosa
3    setosa
4    setosa
5    setosa
6    setosa
7    setosa
8    setosa
9    setosa
Name: species, dtype: object

データフレームの添字として、列名のリストを指定すると複数の列をデータフレームオブジェクトとして抽出することができます。

[9]:
# データフレームの'sepal_length'とspecies'の列の先頭10行のデータ
iris_d[['sepal_length','species']].head(10)
[9]:
sepal_length species
0 5.1 setosa
1 4.9 setosa
2 4.7 setosa
3 4.6 setosa
4 5.0 setosa
5 5.4 setosa
6 4.6 setosa
7 5.0 setosa
8 4.4 setosa
9 4.9 setosa

ilocloc

データフレームオブジェクトの iloc 属性を用いると、NumPyの多次元配列のスライスと同様に、行と列の位置を指定して任意の行と列を抽出することができます。

[10]:
# データフレームの2行のデータ
iris_d.iloc[1]
[10]:
sepal_length       4.9
sepal_width        3.0
petal_length       1.4
petal_width        0.2
species         setosa
Name: 1, dtype: object
[11]:
# データフレームの2行,2列目のデータ
iris_d.iloc[1, 1]
[11]:
3.0
[12]:
# データフレームの1から5行目と1から2列目のデータ
iris_d.iloc[0:5, 0:2]
[12]:
sepal_length sepal_width
0 5.1 3.5
1 4.9 3.0
2 4.7 3.2
3 4.6 3.1
4 5.0 3.6

データフレームオブジェクトの loc 属性を用いると、抽出したい行のインデックス・ラベルや列のラベルを指定して任意の行と列を抽出することができます。複数のラベルはリストで指定します。行のインデックスは各行に割り当てられた番号で、iloc で指定する行の位置とは必ずしも一致しないことに注意してください。

[13]:
# データフレームの行インデックス5のデータ
iris_d.loc[5]
[13]:
sepal_length       5.4
sepal_width        3.9
petal_length       1.7
petal_width        0.4
species         setosa
Name: 5, dtype: object
[14]:
# データフレームの行インデックス5と'sepal_length'と列のデータ
iris_d.loc[5, 'sepal_length']
[14]:
5.4
[15]:
# データフレームの行インデックス1から5と'sepal_length'とspecies'の列のデータ
iris_d.loc[1:5, ['sepal_length','species']]
[15]:
sepal_length species
1 4.9 setosa
2 4.7 setosa
3 4.6 setosa
4 5.0 setosa
5 5.4 setosa

データの条件取り出し

データフレームの列の指定と併せて条件を指定することで、条件にあった行からなるデータフレームを抽出することができます。NumPyの多次元配列の真理値配列によるインデックスアクセスと同様に、条件式のブール演算では、and, or, not の代わりに &, |, ~ を用います。

[16]:
# データフレームの'sepal_length'列の値が7より大きく、'species'列の値が3より小さいデータ
iris_d[(iris_d['sepal_length'] > 7.0) & (iris_d['sepal_width'] < 3.0)]
[16]:
sepal_length sepal_width petal_length petal_width species
107 7.3 2.9 6.3 1.8 virginica
118 7.7 2.6 6.9 2.3 virginica
122 7.7 2.8 6.7 2.0 virginica
130 7.4 2.8 6.1 1.9 virginica

列の追加と削除

データフレームに列を追加する場合は、以下のように、追加したい新たな列名を指定し、値を代入すると新たな列を追加できます。

[17]:
# データフレームに'mycolumn'という列を追加
iris_d['mycolumn']=np.random.rand(len(iris_d.index))
iris_d.head(10)
[17]:
sepal_length sepal_width petal_length petal_width species mycolumn
0 5.1 3.5 1.4 0.2 setosa 0.456118
1 4.9 3.0 1.4 0.2 setosa 0.285426
2 4.7 3.2 1.3 0.2 setosa 0.810478
3 4.6 3.1 1.5 0.2 setosa 0.547663
4 5.0 3.6 1.4 0.2 setosa 0.599085
5 5.4 3.9 1.7 0.4 setosa 0.800863
6 4.6 3.4 1.4 0.3 setosa 0.419813
7 5.0 3.4 1.5 0.2 setosa 0.175686
8 4.4 2.9 1.4 0.2 setosa 0.259131
9 4.9 3.1 1.5 0.1 setosa 0.311892

del 文を用いると、以下のようにデータフレームから任意の列を削除できます。

[18]:
# データフレームから'mycolumn'という列を削除
del iris_d['mycolumn']
iris_d.head(10)
[18]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
5 5.4 3.9 1.7 0.4 setosa
6 4.6 3.4 1.4 0.3 setosa
7 5.0 3.4 1.5 0.2 setosa
8 4.4 2.9 1.4 0.2 setosa
9 4.9 3.1 1.5 0.1 setosa

assign() メソッドを用いると、追加したい列名とその値を指定することで、以下のように新たな列を追加したデータフレームを新たに作成することができます。この際、元のデータフレームは変更されないことに注意してください。

[19]:
# データフレームに'mycolumn'という列を追加し新しいデータフレームを作成
myiris1 = iris_d.assign(mycolumn=np.random.rand(len(iris_d.index)))
myiris1.head(5)
[19]:
sepal_length sepal_width petal_length petal_width species mycolumn
0 5.1 3.5 1.4 0.2 setosa 0.536095
1 4.9 3.0 1.4 0.2 setosa 0.620008
2 4.7 3.2 1.3 0.2 setosa 0.264892
3 4.6 3.1 1.5 0.2 setosa 0.191530
4 5.0 3.6 1.4 0.2 setosa 0.773725

drop() メソッドを用いると、削除したい列名を指定することで、以下のように任意の列を削除したデータフレームを新たに作成することができます。列を削除する場合は、axis 引数に 1 を指定します。この際、元のデータフレームは変更されないことに注意してください。

[20]:
# データフレームから'mycolumn'という列を削除し、新しいデータフレームを作成
myiris2 = myiris1.drop('mycolumn',axis=1)
myiris2.head(5)
[20]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

行の追加と削除

pandas モジュールの append() メソッドを用いると、データフレームに新たな行を追加することができます。以下では、iris_d データフレームの最終行に新たな行を追加しています。ignore_index 引数を True にすると追加した行に新たなインデックス番号がつけられます。

[21]:
# 追加する行のデータフレーム
row = pd.DataFrame([[1,1,1,1, 'setosa']], columns=iris_d.columns)

# データフレームに行を追加し新しいデータフレームを作成
myiris4 = iris_d.append(row, ignore_index=True)
myiris4[-2:]
[21]:
sepal_length sepal_width petal_length petal_width species
149 5.9 3.0 5.1 1.8 virginica
150 1.0 1.0 1.0 1.0 setosa

drop() メソッドを用いると、行のインデックスまたはラベルを指定することで行を削除することもできます。このときに、axis 引数は省略することができます。

[22]:
# データフレームから行インデックス150の行を削除し、新しいデータフレームを作成
myiris4 = myiris4.drop(150)
myiris4[-2:]
[22]:
sepal_length sepal_width petal_length petal_width species
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica

データの並び替え

データフレームオブジェクトの sort_index() メソッドで、データフレームのインデックスに基づくソートができます。また、sort_values() メソッドで、任意の列の値によるソートができます。列は複数指定することもできます。いずれのメソッドでも、inplace 引数により、ソートにより新しいデータフレームを作成する (False) か、元のデータフレームを更新する (True) を指定できます。デフォルトは inplaceFalse になっており、これらのメソッドは新しいデータフレームを作成します。

[23]:
# iris_dデータフレームの4つ列の値に基づいて昇順にソート
sorted_iris = iris_d.sort_values(['sepal_length', 'sepal_width', 'petal_length', 'petal_width'])
sorted_iris.head(10)
[23]:
sepal_length sepal_width petal_length petal_width species
13 4.3 3.0 1.1 0.1 setosa
8 4.4 2.9 1.4 0.2 setosa
38 4.4 3.0 1.3 0.2 setosa
42 4.4 3.2 1.3 0.2 setosa
41 4.5 2.3 1.3 0.3 setosa
3 4.6 3.1 1.5 0.2 setosa
47 4.6 3.2 1.4 0.2 setosa
6 4.6 3.4 1.4 0.3 setosa
22 4.6 3.6 1.0 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa

列の値で降順にソートする場合は、sort_values() メソッドの ascending 引数を False にしてください。

[24]:
# iris_dデータフレームの4つ列の値に基づいて降順にソート
sorted_iris = iris_d.sort_values(['sepal_length', 'sepal_width', 'petal_length', 'petal_width'],ascending=False)
sorted_iris.head(10)
[24]:
sepal_length sepal_width petal_length petal_width species
131 7.9 3.8 6.4 2.0 virginica
117 7.7 3.8 6.7 2.2 virginica
135 7.7 3.0 6.1 2.3 virginica
122 7.7 2.8 6.7 2.0 virginica
118 7.7 2.6 6.9 2.3 virginica
105 7.6 3.0 6.6 2.1 virginica
130 7.4 2.8 6.1 1.9 virginica
107 7.3 2.9 6.3 1.8 virginica
109 7.2 3.6 6.1 2.5 virginica
125 7.2 3.2 6.0 1.8 virginica

データの統計量

データフレームオブジェクトの describe() メソッドで、データフレームの各列の要約統計量を求めることができます。要約統計量には平均、標準偏差、最大値、最小値などが含まれます。その他の統計量を求める pandas モジュールのメソッドは以下を参照してください。

pandasでの統計量計算

[25]:
# iris_dデータフレームの各数値列の要約統計量を表示
iris_d.describe()
[25]:
sepal_length sepal_width petal_length petal_width
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.054000 3.758667 1.198667
std 0.828066 0.433594 1.764420 0.763161
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000

▲データの連結

pandas モジュールの concat() 関数を用いると、データフレームを連結して新たなデータフレームを作成することができます。以下では、iris_d データフレームの先頭5行と最終5行を連結して、新しいデータフレームを作成しています。

[26]:
# iris_dデータフレームの先頭5行と最終5行を連結
concat_iris = pd.concat([iris_d[:5],iris_d[-5:]])
concat_iris
[26]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
145 6.7 3.0 5.2 2.3 virginica
146 6.3 2.5 5.0 1.9 virginica
147 6.5 3.0 5.2 2.0 virginica
148 6.2 3.4 5.4 2.3 virginica
149 5.9 3.0 5.1 1.8 virginica

concat() 関数の axis 引数に 1 を指定すると、以下のように、データフレームを列方向に連結することができます。

[27]:
# iris_dデータフレームの'sepal_length'列と'species'列を連結
sepal_len = pd.concat([iris_d.loc[:, ['sepal_length']],iris_d.loc[:, ['species']]], axis=1)
sepal_len.head(10)
[27]:
sepal_length species
0 5.1 setosa
1 4.9 setosa
2 4.7 setosa
3 4.6 setosa
4 5.0 setosa
5 5.4 setosa
6 4.6 setosa
7 5.0 setosa
8 4.4 setosa
9 4.9 setosa

▲データの結合

pandas モジュールの merge() 関数を用いると、任意の列の値をキーとして異なるデータフレームを結合することができます。結合のキーとする列名は on 引数で指定します。以下では、species の列の値をキーに、2つのデータフレーム、sepal_len, sepal_wid、を結合して新しいデータフレーム sepal を作成しています。

[28]:
# 'sepal_length'と'species'列からなる3行のデータ
sepal_len = pd.concat([iris_d.loc[[0,51,101],['sepal_length']],iris_d.loc[[0,51,101], ['species']]], axis=1)
# 'sepal_width'と'species'列からなる3行のデータ
sepal_wid = pd.concat([iris_d.loc[[0,51,101],['sepal_width']],iris_d.loc[[0,51,101], ['species']]], axis=1)

# sepal_lenとsepal_widを'species'をキーにして結合
sepal = pd.merge(sepal_len, sepal_wid, on='species')
sepal
[28]:
sepal_length species sepal_width
0 5.1 setosa 3.5
1 6.4 versicolor 3.2
2 5.8 virginica 2.7

▲データのグループ化

データフレームオブジェクトの groupby() メソッドを使うと、データフレームの任意の列の値に基づいて、同じ値を持つ行をグループにまとめることができます。列は複数指定することもできます。groupby() メソッドを適用するとグループ化オブジェクト (DataFrameGroupBy) が作成されますが、データフレームと同様の操作を多く適用することができます。

[29]:
# iris_dデータフレームの'species'の値で行をグループ化
iris_d.groupby('species')
[29]:
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x7f99329077f0>
[30]:
# グループごとの先頭5行を表示
iris_d.groupby('species').head(5)
[30]:
sepal_length sepal_width petal_length petal_width species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa
50 7.0 3.2 4.7 1.4 versicolor
51 6.4 3.2 4.5 1.5 versicolor
52 6.9 3.1 4.9 1.5 versicolor
53 5.5 2.3 4.0 1.3 versicolor
54 6.5 2.8 4.6 1.5 versicolor
100 6.3 3.3 6.0 2.5 virginica
101 5.8 2.7 5.1 1.9 virginica
102 7.1 3.0 5.9 2.1 virginica
103 6.3 2.9 5.6 1.8 virginica
104 6.5 3.0 5.8 2.2 virginica
[31]:
# グループごとの'sepal_length'列,'sepal_width'列の値の平均を表示
iris_d.groupby('species')[['sepal_length','sepal_width']].mean()
[31]:
sepal_length sepal_width
species
setosa 5.006 3.418
versicolor 5.936 2.770
virginica 6.588 2.974

▲欠損値、時系列データの処理

pandasでは、データ分析における欠損値、時系列データの処理を支援するための便利な機能が提供されています。詳細は以下を参照してください。

欠損値の処理

時系列データの処理