Pythonデータ解析ライブラリ【Pandas】の基本的な使い方と操作方法



Pandasとは?

Pythonのデータ解析用ライブラリ。
ヘビーユース待ったなしの超便利モジュール。

主な用途はデータフレームと呼ばれるデータ構造の取り扱いを楽に行えるというもの。

データフレームって何やねん?という方は、エクセルを想像していただければ一番わかりやすいかと思います。

縦と、横、それぞれの属性のデータ構造を持つ形です。

Pandasって何ができるの?

ファイルからのデータの読み込みをはじめ、統計量の表示、グラフ化など、データ分析に関する作業を容易に行えます。

中身のコードはCythonまたはC言語なので、Python単体で解析を行うのと比べ、非常に高速に処理を行うことができます。

機械学習のデータの下処理なんかに使うようですが、僕はそこまで大層なことは今のところしていませんが、単純にCSVファイルの処理に使っています。

Pandasはデータの一括操作に便利

大量の行/列分類されたデータを一気に加工、分析するのに非常に適しています。

先ほど、エクセルをイメージとしての引き合いに出しましたが、エクセルを使った操作の場合、関数を使いまくったデータシートだと、
PCスペックにも寄りますが、 5万行も有るとほぼほぼ動かないレベルで動作が鈍ります。

対して、Pandasの操作になると、数十万行レベルであれば比較的サクサク動きます。

CSVの取り扱いなんかも、メソッドを使って一発で読み書きできますので

Pandasを使うには?

Anaconda環境を使っていれば初期状態でインストールされているかと思いますが、その他環境の場合はpipコマンドで一発インストールできます。

Pandasのインストール

sudo pip install pandas #Linux bash
#または
python3 -m pip install pandas

この記事ではPython3系を前提に紹介していきます。

Pandasの使い方

事前インポートが必要です。

import pandas as pd

as pd は「pandasって書くの長いから、省略するよ」って意味です。

DataFrameの作成

data = {'山田':{'国語':60,'算数':80,'理化':90},
        '田中':{'国語':70,'算数':70,'理化':70},
        '佐藤':{'国語':90,'算数':50,'理化':80}
        }

df = pd.DataFrame(data)
print(df)
Out[1]: 
    山田  田中  佐藤
国語  60  70  90
理化  90  70  80
算数  80  70  50

こんな感じで、辞書データからデータフレームを作成できます。

縦の流れの一番上の行を列名またはcolumnと言い、横の流れの一番左端の列を行名またはindexと呼びます。

上のデータの状態では「山田・田中・佐藤」がcolumns、「国語・理化・算数」がindexとなります。

DataFrame軸の反転

縦軸と横軸、つまりindexとcolumnsを入れ替えます。

もちろんデータの中身ごと入れ替わるので行列のクロスする場所の値は変わりません。

df = df.T
print(df)
Out[2]: 
    国語  理化  算数
山田  60  90  80
田中  70  70  70
佐藤  90  80  50

df.Tは軸の反転した新たなデータフレームを返します。
そのままdf変数に再代入することで、書き換えています。

DataFrameの値の参照方法

Pandasでは、いくつかのデータアクセス方法が用意されています。

DataFrameの列を指定して絞り込む

列名を指定して、データを絞り込みアクセスすることができます。

単一の列を絞り込み

print(df['国語'])
Out[3]: 
山田    60
田中    70
佐藤    90
Name: 国語, dtype: int64

#または
print(df.国語)
Out[4]: 
山田    60
田中    70
佐藤    90
Name: 国語, dtype: int64

DataFrameオブジェクトに[](角カッコ)で列名を指定したアクセス、もしくは.(ドット)で続けて列名を入力するアクセスの仕方があります。

参照の状態ではどちらも同じ挙動ですが、代入をしようとすると、若干挙動が変わりますので注意が必要です。

複数列の絞り込み

複数列を同時に絞り込みアクセスすることもできます。

df[]の中に列名のリストを渡すことにより可能になります。つまり、直接書いた場合角カッコが二重になります。

df[['国語','算数']]
Out[4]: 
    国語  算数
山田  60  80
田中  70  70
佐藤  90  50

DataFrameの行を指定して絞り込む

行の絞り込みは、列に比べて少し不自由になります。

[]角カッコのみで行を絞り込んでアクセスしたい場合、使えるのは行番号、または行名のスライスである必要があります。

行番号というのは各行に「0から順に割り当てられた数字」のことです。

同じく列番号も存在します。

df[0:1] #行番号のスライス
Out[4]: 
    国語  理化  算数
山田  60  90  80
#または
df['山田':'山田'] #行名のスライス
Out[4]: 
    国語  理化  算数
山田  60  90  80

スライスというのはリストなどでも使うことがある「特定の範囲を切り取ったデータアクセスの仕方」です。

[]角カッコの中に
[start:stop:step]の3項を用いて表現し、区切り文字には:コロンを使います。

各項は省略可能で、start か stop のどちらか一方の入力だけでも動作しますし、コロンのみの入力でも動作します。

注意したいのは行番号でのスライスアクセスだと[0:1]で一行分の切り取りなのに対して、行名でのスライスをした場合は['山田':'山田’]のように書くと一行分の切り取りになります。

少し違和感がありますが、後者はあまり使うことは少ないので、前者のパターンで覚えておくとよいと思います。

ここでは紹介しませんが、行へのアクセスは.locメソッドを使う方が直感的に行いやすくなると思います。

DataFrameの列の最高値、最低値、平均値、中央値、標準偏差を求める

列の最高値

df['算数'].max()
Out[5]: 80
#または
df.算数.max()
Out[6]: 80

列の最低値

df['理化'].min()
Out[7]: 70
#または
df.理化.min()
Out[8]: 70

列の平均値

df['国語'].mean()
Out[9]: 73.33333333333333
#または
df.国語.mean()
Out[10]: 73.33333333333333

列の中央値

df['理化'].median()
Out[11]: 80.0
#または
df.理化.median()
Out[12]: 80.0

列の標準偏差

df['算数'].std()
Out[13]: 15.275252316519467
#または
df.算数.std()
Out[14]: 15.275252316519467

ちなみにこれらのメソッドは列を指定しなくても適用可能です。

列指定がない場合は各列に対してメソッドが適用され、結果が返されます。

df.max()
Out[15]: 
国語    90
理化    90
算数    80
dtype: int64

df.min()
Out[16]: 
国語    60
理化    70
算数    50
dtype: int64

df.mean()
Out[17]: 
国語    73.333333
理化    80.000000
算数    66.666667
dtype: float64

df.median()
Out[18]: 
国語    70.0
理化    80.0
算数    70.0
dtype: float64

df.std()
Out[19]: 
国語    15.275252
理化    10.000000
算数    15.275252
dtype: float64

新たな列を作る

新規一括代入で列を作る

列名を指定すると参照することが出来ましたが、そこに直接代入することで、列の値を変更できます。

現在、存在しない列名を指定した場合、列を新規作成して代入になります。

df['合計'] = 0
print(df)
Out[20]: 
    国語  理化  算数  合計
山田  60  90  80   0
田中  70  70  70   0
佐藤  90  80  50   0

定数を代入した場合、各列に同一の値が代入されます。

今あるデータを元に新たな列を作る

df['合計'] = df.T.sum()
print(df)
Out[21]: 
山田    230.0
田中    210.0
佐藤    220.0
dtype: float64

sum()は各列の合計値を求めるメソッドです。
df.Tで列と行を転置して行の合計値を'合計'列に代入しています。

同じ理屈で、合計以外にも先ほど紹介した、最高値や、標準偏差などの列を一気に作成することが可能です。

#この書き方でも上のコードと同じ結果になります。
df['合計'] = df.国語 + df.算数 + df.理化

まとめ

何となく使い方と操作方法、出来そうなことが伝わりましたか?

計算の他、文字列操作なんかもゴリゴリ出来きます。