ライブラリ

Pandasを使ってPythonでデータ分析をしよう

         

pandasは「簡潔にデータを扱うために開発されたPythonのライブラリ」です。

CSVなどからデータを読み取り、追加、修正、削除などの処理をすることができます。

ここでは「pandasって何?」「pandasってどう使うの?」といった方へ、pandasの使い方を解説します。

また、「pandasで使える高機能な1次元配列と2次元配列」のようなものとしてよく使われる、SeriesとDataFrameの基本的な使い方も解説します。SeriesやDataFrameは標準で使える配列よりも、より多くの操作が可能で、Pythonでデータを扱う際には必須になりますので、ぜひ使えるようになりましょう。

なお、pandasをインストールしていない場合、まずはpip等でpandasをインストールしてください。

YouTubeも公開していますので、動画や音声で聞きたい方はぜひご覧ください。

Pythonライブラリのpandasとは?

pandasは、Pythonにおいてデータ分析に使われる代表的なライブラリです。先述した様にCSVなどのデータを読み取り・追加修正・削除などの一連の処理が出来るほか、時系列のデータの取扱い、そしてそれらデータの可視化(つまりグラフの作成)まで行うことが出来ます。

Pythonでデータを扱いたい、CSVやExcelによって業務効率を改善したいと考えている方には必須のライブラリです。少し長くなりますが、本稿で解説していきます。

pandasを使ってCSVを読み込む(read_csvメソッド)

早速サンプルコードを見ながらpandasを使ってみましょう。最初はシンプルにCSVに記載されたデータを読み込むプログラムを作ってみます。

まずはCSVファイルを読み込み、変数に入れてみましょう。今回は以下ようなデータが入っているCSVファイルを読み込みます。1列目にNo.を、2列目に氏名を、3列目にその年齢を5名分記載したCSVです。

[CSVファイル]

index,name,age
0,塚田 栄一,45
1,岩村 真尋,21
2,中園 美希,41
3,猪股 幸平,34
4,及川 大介,34

[サンプルコード]

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)
print(data)

csvファイルのデータが変数dataに入っているのが分かります。

1行目で、まずpandasをインポートしましょう。続いてread_csv()メソッドで対象となるCSVファイルを読み込みます。

第一引数はCSVファイルのパス。ここはお使いのファイル名を適宜変えて入れてください。第二引数では、どの列をインデックスとするかを指定しています。今回はindex列を指定しています。

[出力結果]

        name  age
index            
0      塚田 栄一   45
1      岩村 真尋   21
2      中園 美希   41
3      猪股 幸平   34
4      及川 大介   34

入力したデータがそのまま出力されました。

読み込んだデータの情報を取得する

続いて、先ほど読み込んだCSVデータの情報を取得する方法をご紹介します。

データの行数と列数を取得する(shapeメソッド)

データの行数、列数が知りたい場合はshapeを使います。先ほどと同じCSVファイルを使ってやってみましょう。

[サンプルコード]

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)
print(data.shape)

[出力結果]

(5, 2)

カラムの情報を取得する(columns)

読み込んだデータのカラムの情報が知りたい場合はcolumnsを使います。

[サンプルコード]

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)
print(data.columns)

[出力結果]

Index(['name', 'age'], dtype='object')

カラムに記載されている情報が出力されました。columnsでは、他にもカラムの操作(カラム名の変更など)も可能です。

データを先頭から指定した行数取得する-head()-

先頭から指定した行数分データを取得したい場合はhead()を使います。

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)
print(data.head(3))

[出力結果]

        name  age
index            
0      塚田 栄一   45
1      岩村 真尋   21
2      中園 美希   41

データを末尾から指定した行数取得する-tail()-

末尾から指定した行数分データを取得したい場合はtail()を使います。

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)
print(data.tail(3))

[出力結果]

        name  age
index            
2      中園 美希   41
3      猪股 幸平   34
4      及川 大介   34

読み込んだデータに列を追加する

次に、読み込んだcsvデータに、新しい列を追加しましょう。

次の例では、リストの情報を追加しています。

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)

list = [165, 170, 175, 180, 182]
series = pd.Series(list)
data["height"] = series.values

print(data)

[出力結果]

        name  age  height
index                    
0      塚田 栄一   45     165
1      岩村 真尋   21     170
2      中園 美希   41     175
3      猪股 幸平   34     180
4      及川 大介   34     182

最初に読み込んだcsvデータに「height」という列を追加しました。

リストを列に追加するには、pandasのSeries()を使います。引数にリストを渡すと、Seriesというデータ型に変換してくれます。最後にdataに新しく登録する列名をキーとして指定し、Seriesのvaluesでデータを入れています。

csvに出力する

最後に、列を追加したデータをcsvに出力してみましょう。

pandasではcsvやExcelファイル等への出力が簡単に行えます。

import pandas as pd
data = pd.read_csv("test.csv",index_col = 0)

list = [165, 170, 175, 180, 182]
series = pd.Series(list)
data["height"] = series.values

data.to_csv("output.csv")

先ほどのプログラムのprint()の箇所を、to_csv()というメソッドに置き換えています。

第一引数にcsvファイル名を指定することで使用できます。

また、to_excel()を使うとExcelファイルの出力も容易に行えます。

Seriesの基本操作

上記で少しふれたSeriesの基本操作です。Seriesはpandasで使える1次元配列になります。

Seriesの作成

Seriesを初期化するにはpandasのSeries()を使います。

import pandas as pd
s = pd.Series([76, 54, 92])
print(s)

[出力結果]

0    76
1    54
2    92

また、データに名前をつけたい場合は、第二引数を次のようにします。

import pandas as pd
s = pd.Series([76, 54, 92], index=["国語", "英語", "数学"])
print(s)

[出力結果]

国語    76
英語    54
数学    92

値を追加・変更・削除する

次に初期化済みのSeriesに対して、値の追加・変更・削除を行ってみましょう。

import pandas as pd
s = pd.Series([76, 54, 92], index=["国語", "英語", "数学"])
s["日本史"] = 99 #追加
s["英語"] = 62 #変更
s = s.drop("国語") #削除  
print(s)

[出力結果]

英語     62
数学     92
日本史    99

追加と変更はインデックスを使って参照します。

削除はdrop()を使います。drop()の第一引数にインデックスを指定してデータを削除します。

Series同士で足し算する

次に2つのSeriesのデータを足し算してみましょう。

[サンプルコード]

import pandas as pd
s = pd.Series([76, 54, 92], index=["国語", "英語", "数学"])
s2 = pd.Series([34, 61, 22], index=["国語", "英語", "数学"])
print(s + s2)

[出力結果]

国語    110
英語    115
数学    114

2つのSeriesを+演算子で繋げるだけで、全てのデータを足し算できます。

ちなみに片方にしか存在しないインデックスがある場合は「NaN(非数)」になるので注意しましょう。

DataFrameの基本操作

次にDataFrameについて見ていきましょう。

pandasではDataFrameがデータ型の基本で、Seriesの集まりがDataFrameです。

DataFrameの作成

まずはDataFrameの初期化方法です。

csvやexcelを読み込む方法もありますが、今回はリストから作成してみましょう。

[サンプルコード]

import pandas as pd
lists = [[1, 2 ,3], [4, 5, 6], [7, 8, 9]]
d = pd.DataFrame(lists)
d.index = ["1", "2", "3"]
d.columns = ["A", "B", "C"]
print(d)

[出力結果]

   A  B  C
1  1  2  3
2  4  5  6
3  7  8  9

DataFrameはDataFrame()に二次元配列を渡すことで作成できます。

また、index()は行の名前、columns()は列の名前を付けることができます。

列・行を追加する

次にDataFrameに列や行を追加する方法を見ていきましょう。

まずは列の追加方法からご紹介します。

[サンプルコード]

import pandas as pd
lists = [[1, 2 ,3], [4, 5, 6], [7, 8, 9]]
d = pd.DataFrame(lists)
lists2 = [10, 11, 12]
d[3] = lists2
print(d)

[出力結果]

   0  1  2   3
0  1  2  3  10
1  4  5  6  11
2  7  8  9  12

四列目が追加されました。インデックス番号が3の列にリストを渡すことで列を追加しています。

では次に行の追加方法です。列の追加とほとんど変わりません。

[サンプルコード]

import pandas as pd
lists = [[1, 2 ,3], [4, 5, 6], [7, 8, 9]]
d = pd.DataFrame(lists)
lists2 = [10, 11, 12]
d.loc[3] = lists2 #変更
print(d)

[出力結果]

    0   1   2
0   1   2   3
1   4   5   6
2   7   8   9
3  10  11  12

d.loc[3]の箇所を変えています。

行を追加する場合はlocというインスタンス変数を使います。

必要な値を取り出す

最後にDataFrame内の必要な値を取り出す処理を見てみましょう。

値にアクセスするには先ほども使ったlocを使います。

import pandas as pd
lists = [[1, 2, 3], [4, 5, 6]]
d = pd.DataFrame(lists)
d.index = ["1r", "2r"]
d.columns = ["A", "B", "C"]

print(d.loc["2r", "B"])

[出力結果]

5

このdataFrameは次のようになっています。

    A  B  C
1r  1  2  3
2r  4  5  6

今回はこの中から「2r行」の「B列」の値を取得しています。

locは次のように使います。

[構文]

loc[行のインデックス, 列のインデックス]

また、locはスライスに対応しているので、次のように一部を切り取ったデータを取得することも可能です。

[サンプルコード]

import pandas as pd
lists = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
d = pd.DataFrame(lists)
d.index = ["1r", "2r", "3r"]
d.columns = ["A", "B", "C"]

print(d.loc["2r":"3r", "B":"C"])

[出力結果]

    B  C
2r  5  6
3r  8  9

[構文]

loc[行の開始インデックス:終了インデックス, 列の開始インデックス:終了インデックス]

pandasでは、ほかにも様々な処理ができますので、適宜調べてみると良いでしょう。

DataFrameを扱うための関数、メソッド

DataFrameについては、使いこなす上で様々な関数があります。ここからは使用頻度の高いDataFrameをより便利に扱う関数やメソッドを解説していきます。

なお、ここでは次のデータを持つcsvを使用します。

[input.csv]

name_id,name,age
tukada,塚田 栄一,45
iwamura,岩村 真尋,21
nakazono,中園 美希,41
inomata,猪股 幸平,34
oikawa,及川 大介,34

また、特別なことがない限り、次のコードは省略しています。

省略コード:
import pandas as pd
df = pd.read_csv("sample/input.csv")

先頭から数行返却する - head()メソッド

head()はDataFrameの行を、指定した引数の数値分先頭から返却するメソッドです。

[サンプルコード]

head_df = df.head(2)
print(head_df)

[出力結果]

   name_id   name  age
0   tukada  塚田 栄一   45
1  iwamura  岩村 真尋   21

末尾から数行返却する - tail()メソッド

tail()はDataFrameの行を、指定した引数の数値分末尾から返却するメソッドです。

[サンプルコード]

tail_df = df.tail(2)
print(tail_df)

[出力結果]

   name_id   name  age
3  inomata  猪股 幸平   34
4   oikawa  及川 大介   34

行数・列数を返却する - shape

shapeは行数と列数とタプルで返却する「属性」です(メソッドではないので()は必要ありません)。

[サンプルコード]

print(df.shape)

[出力結果]

(5, 3)

また、shapeはインデックス番号に0または1を指定することで、行・列のどちらかだけを取得することもできます。

[サンプルコード]

print(df.shape[0])
print(df.shape[1])

[出力結果]

5
3

各列のデータ型を取得する - dtypes

DataFrameの各列はそれぞれデータ型を保有しています。

dtypesはそれぞれの行のデータ型を全て保有している属性です。

[サンプルコード]

print(df.dtypes)

[出力結果]

name_id    object
name       object
age         int64
dtype: object

行ラベルと列ラベルから値を取得 - loc

locを使えば行ラベルと列ラベルから単数、または複数のデータを取得できます。

行ラベルが必要なので、index_col=0を指定してname_idを行ラベルにしています。

[サンプルコード]

import pandas as pd
df = pd.read_csv("sample/input.csv", index_col=0) #1列目のname_idを行ラベルにする
print(df.loc['iwamura', 'name']) #単独
print(df.loc['iwamura':'inomata', 'name':'age']) #複数要素を取得する場合はスライスを使う

[出力結果]

岩村 真尋

           name  age
name_id             
iwamura   岩村 真尋   21
nakazono  中園 美希   41
inomata   猪股 幸平   34

単数要素を取得したい場合は行ラベル・列ラベルをそれぞれ1つずつ指定します。一方で複数のデータを取得したい場合はスライスを使うことでSeries、またはDataFrameとして取得できます。

また、locは要素の取得だけでなく更新も可能です。

[サンプルコード]

import pandas as pd
df = pd.read_csv("sample/input.csv", index_col=0)
print('修正前:{}'.format(df.loc['iwamura', 'age']))
df.loc['iwamura', 'age'] = 23
print('修正後:{}'.format(df.loc['iwamura', 'age']))

[出力結果]

修正前:21
修正後:23

行番号と列番号で要素を指定 - iloc

loc[]が行ラベル・列ラベルで要素を指定するのに対し、ilocは行番号と列番号で要素を指定します。

[サンプルコード]

print(df.iloc[1, 1])
print(df.iloc[1:4, 0:3])

[出力結果]

岩村 真尋

    name_id   name  age
1   iwamura  岩村 真尋   21
2  nakazono  中園 美希   41
3   inomata  猪股 幸平   34

行ラベル・列ラベルがない場合や、番号の方が都合が良い場合ははilocを使いましょう。

各列ごとの計算を行う - describe()メソッド

describe()は平均や最大値、最小値、標準偏差などの計算を各行で行い出力するメソッドです。

[サンプルコード]

print(df.describe())

[出力結果]

             age
count   5.000000
mean   35.000000
std     9.137833
min    21.000000
25%    34.000000
50%    34.000000
75%    41.000000
max    45.000000

それぞれの計算結果の意味は次の通りです。

項目名意味
countカラム件数
mean 平均
std標準偏差
min最小値
25%第一四分位数
50%第二四分位数(中央値)
75%第三四分位数
max最大値

欠損値かどうかを確認する - isnull()メソッド

isnull()は特定の要素や行・列に欠損値(NaN)が存在するかどうかを確認するためのメソッドです。

ここでは次のcsvデータを読み込みます(データがない箇所がNaNになります)。

[input.csv]

name_id,name,age
tukada,,45
iwamura,岩村 真尋,
nakazono,,
inomata,猪股 幸平,34
oikawa,及川 大介,

このcsvを単純にprint()で出力すると次のようになります。

[サンプルコード]

    name_id   name   age
0    tukada    NaN  45.0
1   iwamura  岩村 真尋   NaN
2  nakazono    NaN   NaN
3   inomata  猪股 幸平  34.0
4    oikawa  及川 大介   NaN

この結果に対してisnull()を使ってみましょう。

単純にisnull()を使った場合は、全ての要素に対してNaNかどうかをチェックし、NaNの場合はTrueを返します。

[サンプルコード]

print(df.isnull())

[出力結果]

   name_id   name    age
0    False   True  False
1    False  False   True
2    False   True   True
3    False  False  False
4    False  False   True

また、any()と併用することで「行・列ごとに1つでもNaNが含まれているか」を確認できます。

any()自体は行・列ごとにTrueが一つでもあればTrueを返却するメソッドです。

[サンプルコード]

print(df.isnull().any()) #何も指定しない場合は列ごと
print(df.isnull().any(axis=1)) #axis=1を指定した場合は行ごと

[出力結果]

name_id    False
name        True
age         True
dtype: bool

0     True
1     True
2     True
3    False
4     True
dtype: bool

欠損値を他の値で穴埋めする - fillna()メソッド

fillna()はNaNがあったら他の値に置き換えるメソッドです。

先ほどのisnull()で使ったcsvを使います。

[サンプルコード]

print(df.fillna(0))

[出力結果]

    name_id   name   age
0    tukada      0  45.0
1   iwamura  岩村 真尋   0.0
2  nakazono      0   0.0
3   inomata  猪股 幸平  34.0
4    oikawa  及川 大介   0.0

引数に値を指定することで、全てのNaNを0に置き換えることができました。 また引数に辞書を使うことで、各列ごとに置き換える値を指定することもできます。

print(df.fillna({'name_id':'none', 'name':'不明', 'age':0}))

[出力結果]

    name_id   name   age
0    tukada     不明  45.0
1   iwamura  岩村 真尋   0.0
2  nakazono     不明   0.0
3   inomata  猪股 幸平  34.0
4    oikawa  及川 大介   0.0

欠損値を除外する - dropna()メソッド

fillna()が置き換えるメソッドである一方、dropna()は欠損値を除外するメソッドです。

次のcsvを使います。

[input.csv]

name_id,name,age
tukada,,
iwamura,岩村 真尋,
,,
inomata,猪股 幸平,
oikawa,及川 大介,

上記のcsvは4行目とage列が全て欠損値という特徴を持っています。

ではdropna()を使ってみましょう。全ての値がNaNである行を除外するにはhow=’all’を指定します。

[サンプルコード]

print(df.dropna(how='all'))

[出力結果]

   name_id   name  age
0   tukada    NaN  NaN
1  iwamura  岩村 真尋  NaN
3  inomata  猪股 幸平  NaN
4   oikawa  及川 大介  NaN

また、全ての値がNaNである列を除外する場合はaxis=1を追加で指定します。

[サンプルコード]

print(df.dropna(how='all', axis=1))

[出力結果]

   name_id   name
0   tukada    NaN
1  iwamura  岩村 真尋
2      NaN    NaN
3  inomata  猪股 幸平
4   oikawa  及川 大介

行・列両方を除外したい場合はdropna()を連続して呼ぶ必要があります。

要素の値を置き換える - replace()メソッド

replace()は指定した値で要素を置き換えるメソッドです。

[サンプルコード]

print(df.replace(34, 24))

[出力結果]

    name_id   name  age
0    tukada  塚田 栄一   45
1   iwamura  岩村 真尋   21
2  nakazono  中園 美希   41
3   inomata  猪股 幸平   24
4    oikawa  及川 大介   24

4,5行目のageが34→24に置き換わっています。

replace()は特に指定がない場合は全ての要素を対象としますが、対象列を指定したい場合は辞書形式で列ラベルを指定します。

次のcsvで試します。

[input.csv]

name_id,name,age,score
tukada,塚田 栄一,45,82
iwamura,岩村 真尋,21,45
nakazono,中園 美希,41,62

塚田さんのageが45かつ岩村さんのscoreも45という特徴を持ったデータです。

岩村さんのscoreのみ置き換えたい場合はreplace()の対象列をscoreのみに限定します。

[サンプルコード]

print(df.replace({'score':{45:95}}))

[出力結果]

    name_id   name  age  score
0    tukada  塚田 栄一   45     82
1   iwamura  岩村 真尋   21     95
2  nakazono  中園 美希   41     62

行・列を指定して削除する - drop()メソッド

drop()は行または列をラベルまたは番号を指定して削除するメソッドです。

[サンプルコード]

import pandas as pd
df = pd.read_csv("sample/input.csv", index_col=0)
df = df.drop('iwamura')
print(df)

[出力結果]

           name  age
name_id             
tukada    塚田 栄一   45
nakazono  中園 美希   41
inomata   猪股 幸平   34
oikawa    及川 大介   34

行を削除する場合は行ラベル(または番号)を指定するだけで良いですが、列を削除する場合はaxis=1を指定する必要があります。

[サンプルコード]

df = df.drop('age', axis=1)
print(df)

[出力結果]

           name
name_id        
tukada    塚田 栄一
iwamura   岩村 真尋
nakazono  中園 美希
inomata   猪股 幸平
oikawa    及川 大介
タイトルとURLをコピーしました