上級マクロ経済学

第6回 Pandas

Author

荻巣嘉高

1 Pandas

データを取り込む

前回までの内容は

  • 基本的な数値の計算
  • プロットの作成

など。 今回取り扱うPandasは

  • データを実際に取り扱う

ためのライブラリ。

インポート

import pandas as pd

として利用する。

  • データフレームと呼ばれる形式を取り扱える。
    • Pythonの中で表を取り扱うイメージ。
  • Excelやcsvファイルを読み込んだりするのに使う。
    • Excelをデータフレームとして読み込みする。
  • データフレームをExcelなどに書き出しもできる。
    • ただ、書き出しするならcsvに書き出すのがおすすめです(圧倒的にバグが少ないので)。

データフレーム

データフレームを、pd.DataFrame()として保存する。

たいてい、dfと称される。

x = ["佐藤","鈴木","近藤"]

df = pd.DataFrame(x)

df
0
0 佐藤
1 鈴木
2 近藤

行列形式のものであれば、2行以上で作成もできる。

import numpy as np # numpyをインポート

x = np.arange(6) # 0から5までの6つの数のリスト
X = x.reshape(3,2) # reshapeで3行2列の行列へ変換
df = pd.DataFrame(X) # Dataframeを作成

df
0 1
0 0 1
1 2 3
2 4 5

インデックスとカラム

DataFrameにはインデックスとカラムのラベルをつけることができる。

index
インデックス(行)名の入ったリストを指定
columns
カラム(列)名の入ったリストを指定
x = np.arange(6).reshape(3,2) # reshapeで行列へ
df = pd.DataFrame(x, index=["a","b","c"], columns=["A","B"])

df
A B
a 0 1
b 2 3
c 4 5

インデックスとカラムの取得

インデックスやカラムはそのリストの取得ができる。

print(df) # dfの確認

print() # 空白行を挿入

print("インデックスリスト") # ラベルの出力
print(df.index) # インデックスリストの出力

print() # 空白行を挿入

print("カラムリスト") # ラベルの出力
print(df.columns) # カラムリストの出力
   A  B
a  0  1
b  2  3
c  4  5

インデックスリスト
Index(['a', 'b', 'c'], dtype='object')

カラムリスト
Index(['A', 'B'], dtype='object')

データへのアクセス

カラム名を入れれば、その列の値がリストになって返ってくる。

x = np.arange(6).reshape(3,2) # reshapeで行列へ
df = pd.DataFrame(x, index=["a","b","c"], columns=["A","B"])

print(df) # dfの確認

print() # 空白行を挿入

df["A"]
   A  B
a  0  1
b  2  3
c  4  5
a    0
b    2
c    4
Name: A, dtype: int64

データフレームの列追加

データフレームの作り方のおすすめは、

  • 空のデータフレームを作って
  • 列を追加していく

という方法。

df[<新しい列名>]=<リスト>とすれば、新しい列が追加される。

  • df[<既にある列名>]としないように注意。
  • 上書きされてしまいます。

列のラベルも追加できるので、管理も楽。

列追加によるデータフレームの作成

df = pd.DataFrame()

name = ["佐藤","鈴木","近藤"]
age = [20,30,28]
hobby = ["サッカー","野球","読書"]

df["名前"] = name
df["年齢"] = age
df["趣味"] = hobby
df
名前 年齢 趣味
0 佐藤 20 サッカー
1 鈴木 30 野球
2 近藤 28 読書
pref = ["お茶","コーヒー","紅茶"]

df["趣味"] = pref # 既存のラベルを指定すると
df # 上書きされてしまう。
名前 年齢 趣味
0 佐藤 20 お茶
1 鈴木 30 コーヒー
2 近藤 28 紅茶

データへのアクセス

基本的に使うのは次の二つ

loc[<行名>, <列名>]
行名、列名で行列を指定。
iloc[<行インデックス>, <列インデックス>]
行インデックス、列インデックスで行列を指定。

行や列にスライス(:)を指定できる。

データアクセスの実例

data = np.arange(6).reshape(3,2)
df = pd.DataFrame(data, index = ["a","b","c"], columns=["A","B"])
df # データフレームの確認
A B
a 0 1
b 2 3
c 4 5
df.loc["c","B"] # インデックスc、カラムBの値
5

:を列や行に指定すると、全てを抜き出す。

df.loc["c",:] # インデックスc、全てのカラム
A    4
B    5
Name: c, dtype: int64
df.loc[:,"B"] # カラムB、すべてのインデックス
a    1
b    3
c    5
Name: B, dtype: int64
df.loc[:"b","A"] # インデックスbまで、カラムA
# locの指定では最後の値(ここでは"b")も含まれることに注意!
a    0
b    2
Name: A, dtype: int64
df.iloc[2,1] # 2行1列の値(0始まり)
5

:を列や行に指定すると、全てを抜き出す。

df.iloc[2,:] # 2行目全ての値
A    4
B    5
Name: c, dtype: int64
df.iloc[:2,0] # 0列目の0~1行目まで
a    0
b    2
Name: A, dtype: int64

ndarrayへの変換

データフレームは、.valuesでndarrayに変換できる。

data = np.arange(6).reshape(3,2)
df = pd.DataFrame(data, index = ["a","b","c"], columns=["A","B"])
df # データフレームの確認
A B
a 0 1
b 2 3
c 4 5
df.values # 全部変換
array([[0, 1],
       [2, 3],
       [4, 5]])
df.iloc[2,:].values # 一部を抜き出して変換
array([4, 5])

データフレームの読み込み

read_excel(<Excelファイルへのパス>)
Excelファイルの読み込み
read_csv(<csvファイルへのパス>)
csvファイルの読み込み
  1. 配布している wage_and_productivity.xlsx ファイルを、作業ファイルと同じフォルダ(ディレクトリ)に置いてください。
  • Google Colaboratoryであれば、ファイルのアップロードをすればOKです。
  1. 相対パスを確認してください。
    • 相対パスのスタート地点は、今作業しているファイルが存在しているフォルダ(ディレクトリ)です。
    • スタート地点と同じフォルダ(ディレクトリ)にあるファイルへは./<ファイル名>でアクセスできます。
    • 実際は同じフォルダにあれば./を省略してもアクセスできますが、コーディングのクセとしてつけておくことをお勧めします。

Excel読み込みのコード例

今回のケースの例では、以下のようにします。 (head()関数で、読み込んだdfの最初の方だけ表示しましょう。)

df = pd.read_excel("./wage_and_productivity.xlsx")

df.head() # 最初の5行を表示
2020年 労働生産性(円/時間) 賃金所得(千円)
0 北海道 8997.702921 4232.5
1 青森 8946.026251 3667.9
2 岩手 8336.011457 3790.4
3 宮城 8875.070576 4459.4
4 秋田 8700.560140 3758.0

read_excelの補足

  • 読み込むシートをsheet_name=<シートの名前>指定できます。デフォルトでは、一番最初のシートが読み込まれます。
  • index_col=<カラムのNo>でインデックスにするカラムの番号を指定できます。
  • header=<行のNo>で、カラムにする行を指定できます。ただし、headerで指定した行より前の行は読み込まれません
df = pd.read_excel("wage_and_productivity.xlsx", index_col=0)

df.head()
労働生産性(円/時間) 賃金所得(千円)
2020年
北海道 8997.702921 4232.5
青森 8946.026251 3667.9
岩手 8336.011457 3790.4
宮城 8875.070576 4459.4
秋田 8700.560140 3758.0
df.index
Index(['北海道', '青森', '岩手', '宮城', '秋田', '山形', '福島', '茨城', '栃木', '群馬', '埼玉', '千葉',
       '東京', '神奈川', '新潟', '富山', '石川', '福井', '山梨', '長野', '岐阜', '静岡', '愛知', '三重',
       '滋賀', '京都', '大阪', '兵庫', '奈良', '和歌山', '鳥取', '島根', '岡山', '広島', '山口', '徳島',
       '香川', '愛媛', '高知', '福岡', '佐賀', '長崎', '熊本', '大分', '宮崎', '鹿児島', '沖縄'],
      dtype='object', name='2020年')

read_csvについて

  • csvファイルは、テキストファイルです。
    • どんな中身か気になる人は、テキストエディタ(メモ帳など)でcsvファイルを開いてみてください。
  • ファイルごとに文字コードが決まっています。
    • read_csvで読み込む際に文字コードを指定しないと文字化けしたり、読み込めなかったりします。
    • 文字コードは、encoding=<文字コード>で指定できます。
    • 日本語が含まれる場合、文字コードはshift-jisで指定すればOKな場合が多いです。
  • バグが少ない&ファイルが軽いので、可能ならこちらをメインに使うべき。

read_csvの例

エラー例


df = pd.read_csv("wage_and_productivity.csv", index_col=0) # 日本語を含んでいると、普通に読み込むとエラーが出る。文字コードの問題。

OK例

df = pd.read_csv("wage_and_productivity.csv", index_col=0, encoding="shift-jis") # 文字コードをshift-jisに指定すると読み込める

df.head()
労働生産性(円/時間) 賃金所得(千円)
2020年
北海道 8997.702921 4232.5
青森 8946.026251 3667.9
岩手 8336.011457 3790.4
宮城 8875.070576 4459.4
秋田 8700.560140 3758.0

Excelやcsvへの書き出し

to_excel(<Excelファイルのパス>)
Excelファイルへの書き出し
to_csv(<csvファイルのパス>)
csvファイルへの書き出し

to_excelto_csvを使うことで、データフレームを保存できます。

df = pd.DataFrame()

name = ["佐藤","鈴木","近藤"]
age = [20,30,28]
hobby = ["サッカー","野球","読書"]

df["名前"] = name
df["年齢"] = age
df["趣味"] = hobby
df # dfの確認
名前 年齢 趣味
0 佐藤 20 サッカー
1 鈴木 30 野球
2 近藤 28 読書

次のコマンドで、作業ファイルと同じフォルダにtest.xlsxが作成されていることを確認してください。

df.to_excel("./test.xlsx") # 書き出し

データフレームの検索

dfを条件で検索できる。 以下を参照。

df0 = pd.DataFrame()

name = ["佐藤","鈴木","近藤"]
age = [20,30,28]
hobby = ["サッカー","野球","読書"]

df0["名前"] = name
df0["年齢"] = age
df0["趣味"] = hobby
df0 # df0の確認
名前 年齢 趣味
0 佐藤 20 サッカー
1 鈴木 30 野球
2 近藤 28 読書
df["年齢"]<30 # 年齢が30より下で条件をつける(真偽判定)
0     True
1    False
2     True
Name: 年齢, dtype: bool
df[df["年齢"]<30] # dfから年齢が30より下の行を抜き出す
名前 年齢 趣味
0 佐藤 20 サッカー
2 近藤 28 読書

まとめ

  • データ解析をするためには、Pandasは必携。
    • Excelなどの表データを読み込むのに、一番安定したpythonライブラリ。
  • Pandasの挙動は少しクセがあるように感じるかもしれない。こればかりは慣れるほかない。