およそ半年ぶりの更新ですが,何事もなかったかのように平然とエントリをし始めましたが...
(つくばチャレンジにも参加しました.結果は残念でしたが...また取り組みをアップします.)
最近会社で機械学習の勉強をしていて,その際に Pandas というライブラリを使う必要があったので,概要と使い方を備忘録としてまとめておきます.
勉強に使ったのは下記の本です.一年半くらい前に買って,積読状態になっていたので,活用できる機会ができてよかった...
Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理
- 作者: Wes McKinney,小林儀匡,鈴木宏尚,瀬戸山雅人,滝口開資,野上大介
- 出版社/メーカー: オライリージャパン
- 発売日: 2013/12/26
- メディア: 大型本
- この商品を含むブログ (17件) を見る
- pandas のデータ構造
大まかにいうと,Series と DataFrame という二種類のデータ構造がある.シリーズというのは,一次元の配列らしいが,Numpyの配列と異なるところは,インデックスというデータラベルの配列がつくところ.まず,IPython を使って Series で遊んでみます.
ライブラリのインポート.
from pandas import Series, DataFrame import pandas as pd
- シリーズオブジェクトの作成
In [131]: series = Series([1, 10, 100, 1000]) In [132]: series Out[132]: 0 1 1 10 2 100 3 1000 dtype: int64
上の出力を見てみると,Numpyの配列とは違って,勝手にインデックスが付与されていることがわかります.
また,このインデックスに関しては,自分で好きなものを付与することもできます.
- インデックスラベルを指定したシリーズオブジェクトの作成
In [134]: series_w_index_specified = Series([1, 10, 100, 1000], index=['JPN', 'USA', 'GER', 'GBR']) In [135]: series_w_index_specified Out[135]: JPN 1 USA 10 GER 100 GBR 1000 dtype: int64
- データフレームオブジェクトの作成
シリーズが一次元の配列であるのに対し,こちらは二次元の配列というかテーブル風のデータ構造.
In [151]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'], ...: 'year' : ['2000', '2001', '2002', '2001', '2002'], ...: 'pop' :['1.5', '1.7', '3.6', '2.4', '2.9']} In [152]: frame = DataFrame(data) In [153]: frame In [154]: Out[153]: pop state year 0 1.5 Ohio 2000 1 1.7 Ohio 2001 2 3.6 Ohio 2002 3 2.4 Nevada 2001 4 2.9 Nevada 2002
- データセットのマージ
これが使いたかったんです.以前 SQL を使ってデータベースの処理をしていたことがあったんですが,テーブルの結合とかと等価の処理を自分で作るのは時間もかかるしめんどくさいし..ということで,pandas を使ってデータセットをマージする方法をメモ.
pandas.merge : データフレームに含まれる行を一つ以上のキーでマージできる.
pandas.concat : 複数の列のオブジェクトを貼り合わせたり,積み上げたりすることが可能.
-
- pandas.merge を使ったデータフレームのマージ
In [9]: df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'], ...: 'data1': range(7)}) In [10]: df2 = DataFrame({'key': ['a', 'b', 'd'], ...: 'data2': range(3)}) In [11]: df1 Out[11]: data1 key 0 0 b 1 1 b 2 2 a 3 3 c 4 4 a 5 5 a 6 6 b In [12]: df2 Out[12]: data2 key 0 0 a 1 1 b 2 2 d
上で作成したデータを,pandas.merge を使ってマージします.
超簡単ですね.ありがたやありがたや.
In [15]: pd.merge(df1, df2, on = 'key') Out[15]: data1 key data2 0 0 b 1 1 1 b 1 2 6 b 1 3 2 a 0 4 4 a 0 5 5 a 0
結合する列の名前が左右のテーブルで異なるときもあると思いますが,こちらに関しても下記のようにすれば結合できるみたいです.
両方にキーが存在する行のみがマージされた結果に残されている様子が見て取れます.この結合を内部結合といい,結果に表れるキーは両者の共通集合になります.
In [22]: df3 = DataFrame({'lkey':['b', 'b', 'a', 'c', 'a', 'a', 'b'], ...: 'data1': range(7)}) In [23]: df4 = DataFrame({'rkey':['a', 'b', 'd'], ...: 'data2': range(3)}) In [24]: pd.merge(df3, df4, left_on='lkey', right_on='rkey') Out[24]: data1 lkey data2 rkey 0 0 b 1 b 1 1 b 1 b 2 6 b 1 b 3 2 a 0 a 4 4 a 0 a 5 5 a 0 a
一方で,どちらか片方に存在するキーも消したくない場合もあると思います.この場合には,外部結合を実施すれば結合できます.
ただし,ペアとなるキーが相手方に存在しない場合はそのデータはNaNとなります.下記の実行結果を見てもわかる通り,結合ペアのキーのない箇所はデータが NaN になっています.
In [25]: pd.merge(df3, df4, left_on='lkey', right_on='rkey', how='outer') Out[25]: data1 lkey data2 rkey 0 0.0 b 1.0 b 1 1.0 b 1.0 b 2 6.0 b 1.0 b 3 2.0 a 0.0 a 4 4.0 a 0.0 a 5 5.0 a 0.0 a 6 3.0 c NaN NaN 7 NaN NaN 2.0 d