Pandasの使い方(データ解析)
1. 学習の目標
このレッスンでは Pandas というパッケージライブラリを紹介します。
Pandasを使うことで、CSVファイルに保存されているデータをPythonのプログラム内に読み込んで、データ処理をすることができるようになります。また、通常の「テキストファイルを読み込む方法」よりも楽にデータを扱えます。
ここではCSVファイルを読み込み、作成された「DataFrame」という型のオブジェクトの簡単な操作ができるようになることが目標です。また、DataFrameという型はndarrayとは異なるものなので、それぞれに変換する方法についても学びます。
- CSVファイルを読み込む
- データを参照・表示する
- DataFrameとndarrayを相互変換する
2. CSVファイルを読み込む
CSVファイルは、データをカンマ(,
)で区切った形式として保存したテキストファイルです。ExcelやGoogleのスプレッドシートなどで「表」として開くことができます。異なる表計算ソフトの間でも同じように開けることが特長です。
このレッスンでは Machine Learning Repository で配布されている「bank.csv」のファイルを使います。同じファイルを用意しましたので、以下のリンクからダウンロードしてください。zip形式で圧縮したファイルですので、ダウンロードした後に解凍しましょう。解凍して出てきた bank.csv ファイルを、Cloud9の本レッスン用のノートブックがある場所と同じところにアップロードしてください(PCからアップするファイルやフォルダをAWS Cloud9のフォルダに向かってドラッグ&ドロップしましょう)。
このbank.zipは、銀行が持っている顧客情報のリスト(サンプル)で、以下の情報で構成されたデータが4500件程度、保存されています。
列名 | 概要 |
---|---|
age |
年齢 |
job |
職業 |
marital |
結婚した経験の有無 |
education |
最終学歴 |
default |
債務不履行かどうか |
balance |
口座残高 |
housing |
住宅ローンの有無 |
loan |
パーソナルローンの有無 |
contact |
連絡手段 |
day |
最後に営業の連絡をした日にち(日) |
month |
最後に営業の連絡をした日にち(月) |
duration |
現在実施中のキャンペーンで最後に営業の連絡をした日からの経過日数 |
campaign |
現在実施中のキャンペーンで営業の連絡をした回数 |
pdays |
前回のキャンペーンで最後に営業の連絡をした日からの経過日数 |
previous |
前回のキャンペーンで営業の連絡をした回数 |
poutcome |
前回のキャンペーンでの結果 |
y |
定期預金の契約の有無 |
bank.csv をJupyterLabのノートブックファイルが保管されているディレクトリへ格納してください。また、JupyterLabで新規ノートブックを作成し、
Lesson4
という名前にしてください。
まずはPandasをモジュールとしてインポートします。後ほどNumPyも使いますので、併せてインポートしておきます。
import pandas as pd import numpy as np
では bank.csv を読み込みましょう。pd.read_csv()
で読み込めます。引数にCSVファイルの場所(パス)を指定します。これだけです。bank.csv
の1行目は列の見出しとなっていますが、それをそのまま「列名」として読み込んでくれるのも便利な点となっています。
bank_data = pd.read_csv("bank.csv")
これを実行することで、変数 bank_data
には bank.csv
に保存されていた銀行の顧客情報が格納されます。ここでひとつ注意したいのは、bank_data
のデータ型です。調べてみると、以下のとおりです。
print(type(bank_data))
出力結果:
<class 'pandas.core.frame.DataFrame'>
DataFrame
と表示されました。これはPandasにおける2次元配列のデータ型です。(1次元配列は Series
というデータ型になります。)Python標準のリストや、NumPyのndarrayとは似たようなものですが異なるデータ型です。
3. データを参照・表示する
3.1 とりあえず表示する
DataFrameであることの利点のひとつは、JupyterLabでデータを表示しようとした場合、DataFrame型オブジェクトのメソッドに表示を任せると「綺麗な表」を出力してくれる点です。
print()
は利用せず、JuputerLabに bank_data
とだけ記述して実行してみてください。
bank_data
出力結果:
このように、JupyterLabとPandasが連携して、きれいな表が出力されます。Python標準の print()
でデータを表示しようとすると、単純にデータを文字で表示するだけとなり、このようにはなりません。
なお、bank_data には4500件のデータが入っているため、途中省略されているものの、非常に縦長の表示になりました。正常にCSVが読み込まれたかを確認したいだけなら
head()
というメソッドを利用してください。先頭から5件までしか表示しません。
bank_data.head()
出力結果:
サンプルコードは省略しますが、逆に末尾のデータを表示する tail()
も存在します。
3.2 スライス
位置の数値でスライスする
DataFrameでもリストやndarrayのようにスライスが可能です。配列名.iloc[行のスライス指定][列のスライス指定]
もしくは
配列名.iloc[行のスライス指定, 列のスライス指定]
のように記述します。
bank_data.iloc[1, 1] # 1番目のみ
出力結果:
bank_data.iloc[0:3, 0:3] # 0番目から4番目まで
出力結果:
bank_data.iloc[:11:2, :11:2] # 先頭から12番目まで(増分2で)
出力結果:
列名でスライスする
DataFrameでは 配列名.loc[]
を使うことで列名によるデータの参照が可能です。1列だけ指定したい場合は列名の文字列のみを、複数の列を指定したい場合は列名の文字列をリストにしたものを loc[]
の
[]
内に記述してください。以下、一例です。
# bank_data.iloc[1, 1] と同じ出力結果になる bank_data.loc[1, "job"]
# bank_data.iloc[0:3, 0:3] と同じ出力結果になる bank_data.loc[0:2, ["age", "job", "marital"]]
# bank_data.iloc[:11:2, :11:2] と同じ出力結果になる bank_data.loc[:10:2, ["age", "marital", "default", "housing", "contact", "month"]]
それぞれ、iloc
の場合と同じ出力結果になることを確認してください。
loc
の場合は iloc
と異なり、行の指定でスライスを利用する場合、範囲が終わる場所は 終了位置
の場所も含まれています。 "終了位置 - 1" ではありません。上記のサンプルで iloc
では
bank_data.iloc[0:3, 0:3]
としていますが loc
では
bank_data.loc[0:2, ["age", "job", "marital"]]
です。少なくともカリキュラムで利用しているPandasのバージョンでは、このような仕様となっていますので注意しましょう。
3.3 特定の条件による抽出
ある列を指定し、その列の値が特定の条件を満たしている行のみを抽出する方法があります。
query()を使う方法
ひとつは query()
という関数を使う方法です。 配列名.query(条件式)
のように記述します。たとえば age
列の値が35以上のデータを抽出したい場合、以下のように記述します。
bank_data.query("age >= 35")
Out[]: 3049 rows × 17 columns
(表は省略)
文字列型のデータを検索したい場合、その文字列を、条件式を囲むクォーテーションとは別のクォーテーションで囲まなければなりません。条件式全体にダブルクォーテーションを使った際は、探したい文字列値をシングルクォーテーションで囲ってください。以下は
marital
列の値が「single」のデータを抽出したい場合の記述方法です。
bank_data.query("marital == 'single'")
Out[]: 1196 rows × 17 columns
(表は省略)
query()を使わない方法
query()
関数は使わない方法もあります。
# ageが35以上のデータを抽出 bank_data[bank_data["age"] >= 35]
# maritalが「single」のデータを抽出 bank_data[bank_data["marital"] == "single"]
それぞれ query()
を使う場合と結果が一致することを確認してください。
複数の条件を指定する方法
query()
を使う場合と使わない場合の両方で、論理積・論理和による複数条件の指定が可能です。
query()を使う方法による複数条件の指定
# ageが35以上で、なおかつ、maritalが「single」のデータを抽出 bank_data.query("age >= 35 and marital == 'single'")
query()を使わない方法による複数条件の指定
こちらの場合、and
と or
は利用できませんので、&
および |
を使いましょう。
# ageが35以上で、なおかつ、maritalが「single」のデータを抽出 bank_data[(bank_data["age"] >= 35) & (bank_data["marital"] == "single")]
どちらも出力内容は 437 rows × 17 columns
で同一の表になっていることを確認してください。
4. DataFrameとndarrayを相互変換する
PandasにはPandasで、NumPyにはNumPyの便利な命令が、それぞれで用意されています。DataFrameで処理すべきかndarrayに変換するべきかは、処理内容によります。そこで、それぞれのデータ型への相互変換が必要です。
4.1 DataFrameからndarrayに変換する
DataFrameからndarrayへの変換は、DataFrameのオブジェクトが持つ values
プロパティを参照すればOKです。
引き続き bank.csv を読み込んで作成した bank_data を利用します。
nd_bank_data = bank_data.values
print(type(nd_bank_data))
print(nd_bank_data)
出力結果:
<class 'numpy.ndarray'>
[[30 'unemployed' 'married' ... 0 'unknown' 'no']
[33 'services' 'married' ... 4 'failure' 'no']
[35 'management' 'single' ... 1 'failure' 'no']
...
[57 'technician' 'married' ... 0 'unknown' 'no']
[28 'blue-collar' 'married' ... 3 'other' 'no']
[44 'entrepreneur' 'single' ... 7 'other' 'no']]
なお values
プロパティには列見出しの情報は入っていません。列見出しが欲しいときは 配列名.columns.values
という指定をしてください。列見出しがndarrayの形式で取得できます。
nd_bank_columns = bank_data.columns.values
print(type(nd_bank_columns))
print(nd_bank_columns)
出力結果:
<class 'numpy.ndarray'>
['age' 'job' 'marital' 'education' 'default' 'balance' 'housing' 'loan'
'contact' 'day' 'month' 'duration' 'campaign' 'pdays' 'previous'
'poutcome' 'y']
4.2 ndarrayからDataFrameに変換する
逆にndarrayからDataFrameのオブジェクトを作るには pd.DataFrame()
を実行します。pd.DataFrame()
は
data
と columns
というキーワード引数を持っています。data
にはデータの値そのものを、また
colums
には列見出しの情報を ndarray形式で指定してください。
re_bank_data = pd.DataFrame(data = nd_bank_data, columns = nd_bank_columns)
print(type(re_bank_data))
re_bank_data.head()
出力結果:
5. まとめ
このレッスンではPandasの使い方を学びました。CSVファイルからデータを読み込むことが簡単にできるライブラリです。
次のレッスンでは、画像ファイルを読み込むことができるライブラリを紹介します。