・Pandas入門
今現在、プロジェクトでPythonのライブラリ「Pandas」を使っているので、覚書も含め纏めたいと思います。
不備などありましたら、ご指摘をお願い致します。
・Pandasとは
Pandasとはデータ解析、操作を迅速で快適かつ簡単に行なうことができるPythonで作られたオープンソースライブラリになります。
開発者であるWes McKinneyは、財務データを定量分析するための高性能で柔軟なツールを欲しており、AQR Capital Managementにて2008年にpandasの開発を開始した。 AQRを去る前に上司を説得し、ライブラリの一般公開が可能となった。
別のAQR従業員であるChang Sheは、2012年からこのライブラリの2番目の主要コントリビューターとなった。同時期に、Pythonコミュニティでライブラリが普及し、さらに多くのコントリビューターがプロジェクトに加わることになった。
2015年、pandasはNumFOCUS(アメリカ合衆国における501(c)(3)非営利慈善団体)の財政出資プロジェクトとして署名した。
・Pandasのインストール
pip install pandas
・使い方
Pandasを利用するには通例、以下のようにPandasライブラリを読み込みます。
import pandas as pd
・Pandasのデータ構造
Pandasでは1次元配列のSeries、2次元配列のDataframe、3次元配列のPanelが用意されています。
今回はよく利用するSeries、Dataframeについてまとめていきます。
・Series生成
Seriesの生成は以下のようになります。
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
各パラメータの説明
引数 | 内容 |
---|---|
・data | データ:配列相当のもの、ディクショナリ、数値 データがディクショナリの場合には引数の順序は維持されます。 |
・index | データ:配列相当のもの、または1次元配列のインデックス。 デフォルトとしてRangeIndexが0から1, 2, …, nの順番で設定される。ディクショナリ相当のデータでインデックスが指定されていない場合、キーがインデックスとして使用される。 |
・dtype | データ:str型、numpy.dtype、ExtensionDtype 出力されるSeriesのデータ型を指定したい場合に設定。Noneの場合は型推論で指定される。 |
・name | データ:str型 Seriesの列名を設定 |
・copy | データ:bool型 デフォルト:False 入力されたデータの参照を利用するか、コピーを利用するかを指定。 |
pd.Series(["name1","name2","name3"])
index | col1 |
---|---|
0 | name1 |
1 | name2 |
2 | name3 |
dtype: object |
・DataFrame生成
DataFrameの生成は以下のようになります。
pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=None)
各パラメータの説明
引数 | 内容 |
---|---|
・data | データ:ndarray、Iterable、ディクショナリ、DataFrame ディクショナリにはSeries、配列、定数、dataclass、リスト相当のオブジェクトを含めれます。データがディクショナリの場合、列の順番は挿入の順番に準拠します。 |
・index | データ:インデックスまたは配列相当のもの インデックスを配列などで指定。インデックスを指定していない場合は、デフォルトとしてRangeIndexが0から1, 2, …, nの順番で設定される。 |
・columns | データ:インデックスまたは配列相当のもの データにカラム名がない場合、結果にカラム名を設定。デフォルトとしてRangeIndexが0から1, 2, …, nの順番で設定される。 |
・dtype | データ:dtype デフォルト None 出力されるDataframeのデータ型を指定したい場合に設定。Noneの場合は型推論で指定される。 |
・copy | データ:bool型 デフォルト:None 入力データのコピー。 ディクショナリのデフォルトの設定はNoneでcopy=Trueの振る舞いをする。データフレーム、二次元配列のデータのデフォルトの設定はNoneでcopy=Falseの振る舞いをする。version 1.3.0.で変更されているようです。 |
data_list = [["name1", "address1", "M", pd.Timestamp("20000101"), 170.0, 60.0],["name2", "address2", "F", pd.Timestamp("20000102"), 160.0, 50.0],["name3", "address3", "M", pd.Timestamp("20000103"), 180.0, 70.0]]
df = pd.DataFrame(data_list, columns=["col1", "col2", "col3", "col4", "col5", "col6"])
index | col1 | col2 | col3 | col4 | col5 | col6 |
---|---|---|---|---|---|---|
0 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 |
1 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 |
2 | name3 | address3 | M | 2000-01-03 | 180.0 | 70.0 |
・列データの追加
new_data_list = [1,2,1]
df["col7"] = new_data_list
index | col1 | col2 | col3 | col4 | col5 | col6 | col7 |
---|---|---|---|---|---|---|---|
0 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 |
1 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 |
2 | name3 | address3 | M | 2000-01-03 | 180.0 | 70.0 | 1 |
要素の選択
列を指定した取得方法(二つは同一結果)
df["col1"]
index | col1 |
---|---|
0 | name1 |
1 | name2 |
2 | name3 |
Name: col1, dtype: object |
df.col1
index | col1 |
---|---|
0 | name1 |
1 | name2 |
2 | name3 |
Name: col1, dtype: object |
行を指定した取得方法
df[0:2]
index | col1 | col2 | col3 | col4 | col5 | col6 |
---|---|---|---|---|---|---|
0 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 |
1 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 |
数値で位置を指定した行の取得方法
df.iloc[2]
Name | Value |
---|---|
col1 | name3 |
col2 | address3 |
col3 | M |
col4 | 2000-01-0300:00:00 |
col5 | 180 |
col6 | 70 |
Name: 2, dtype: object |
行および列を数値位置で指定しての取得方法。
df.iloc[[0, 2], [0, 2]]
index | col1 | col3 |
---|---|---|
0 | name1 | M |
2 | name3 | M |
行を指定しての取得方法
df.iloc[[0,2], :]
|index|col1|col2|col3|col4|col5|col6|
|-|-|-|-|-|-|-|-|
|0|name1|address1|M|2000-01-01|170.0|60.0|
|2|name3|address3|M|2000-01-03|180.0|70.0|
Boolean indexing
df[df["col5"] > 160]
|index|col1|col2|col3|col4|col5|col6|
|-|-|-|-|-|-|-|-|
|0|name1|address1|M|2000-01-01|170.0|60.0|
df[df["col6"].isin([50.0, 70.0])]
|index|col1|col2|col3|col4|col5|col6|
|-|-|-|-|-|-|-|-|
|1|name2|address2|F|2000-01-02|160.0|50.0|
|2|name3|address3|M|2000-01-03|180.0|70.0|
・グループ化
データ
data_list = [["name1", "address1", "M", pd.Timestamp("20000101"), 170.0, 60.0,1],["name2", "address2", "F", pd.Timestamp("20000102"), 160.0, 50.0,2],["name3", "address3", "M", pd.Timestamp("20000103"), 180.0, 70.0,1],["name4", "address4", "F", pd.Timestamp("20000104"), 150.0, 40.0,1],["name5", "address5", "M", pd.Timestamp("20000105"), 190.0, 80.0,2],["name6", "address6", "M", pd.Timestamp("20000106"), 200.0, 90.0,1],["name7", "address7", "F", pd.Timestamp("20000107"), 140.0, 40.0,1],["name8", "address8", "F", pd.Timestamp("20000108"), 150.0, 50.0,2],["name9", "address9", "F", pd.Timestamp("20000109"), 170.0, 60.0,1],["name10", "address10", "M", pd.Timestamp("20000110"), 170.0, 60.0,2]]
df = pd.DataFrame(data_list, columns=["col1", "col2", "col3", "col4", "col5", "col6", "col7"])
|index|col1|col2|col3|col4|col5|col6|col7|
|-|-|-|-|-|-|-|-|-|
|0|name1|address1|M|2000-01-01|170.0|60.0|1|
|1|name2|address2|F|2000-01-02|160.0|50.0|2|
|2|name3|address3|M|2000-01-03|180.0|70.0|1|
|3|name4|address4|F|2000-01-04|150.0|40.0|1|
|4|name5|address5|M|2000-01-05|190.0|80.0|2|
|5|name6|address6|M|2000-01-06|200.0|90.0|1|
|6|name7|address7|F|2000-01-07|140.0|40.0|1|
|7|name8|address8|F|2000-01-08|150.0|50.0|2|
|8|name9|address9|F|2000-01-09|170.0|60.0|1|
|9|name10|address10|M|2000-01-10|170.0|60.0|2|
列を指定してグループ化した結果を取得する方法。
gp_df = df.groupby("col3")
df.loc[gp_df['col5'].idxmax(),:]
|index|col1|col2|col3|col4|col5|col6|col7|
|-|-|-|-|-|-|-|-|-|
|8|name9|address9|F|2000-01-09|170.0|60.0|1|
|5|name6|address6|M|2000-01-06|200.0|90.0|1|
複数列を指定してグループ化した結果を取得する方法。
gp_df = df.groupby(["col3","col7"])
df.loc[gp_df['col5'].idxmax(),:]
|index|col1|col2|col3|col4|col5|col6|col7|
|-|-|-|-|-|-|-|-|-|
|8|name9|address9|F|2000-01-09|170.0|60.0|1|
|1|name2|address2|F|2000-01-02|160.0|50.0|2|
|5|name6|address6|M|2000-01-06|200.0|90.0|1|
|4|name5|address5|M|2000-01-05|190.0|80.0|2|
・マージ処理
concat
縦方向に単純に結合する方法。
データ1
data_list = [["101","name1", "address1", "M", pd.Timestamp("20000101"), 170.0, 60.0,1],["102","name2", "address2", "F", pd.Timestamp("20000102"), 160.0, 50.0,2],["103","name3", "address3", "M", pd.Timestamp("20000103"), 180.0, 70.0,1],["104","name4", "address4", "F", pd.Timestamp("20000104"), 150.0, 40.0,1],["105","name5", "address5", "M", pd.Timestamp("20000105"), 190.0, 80.0,2]]
df = pd.DataFrame(data_list, columns=["ID","col1", "col2", "col3", "col4", "col5", "col6", "col7"])
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 |
---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 |
2 | 103 | name3 | address3 | M | 2000-01-03 | 180.0 | 70.0 | 1 |
3 | 104 | name4 | address4 | F | 2000-01-04 | 150.0 | 40.0 | 1 |
4 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2 |
データ2
data_list2 = [["106","name6", "address6", "M", pd.Timestamp("20000106"), 200.0, 90.0,1],["107","name7", "address7", "F", pd.Timestamp("20000107"), 140.0, 40.0,1],["108","name8", "address8", "F", pd.Timestamp("20000108"), 150.0, 50.0,2],["109","name9", "address9", "F", pd.Timestamp("20000109"), 170.0, 60.0,1],["110","name10", "address10", "M", pd.Timestamp("20000110"), 170.0, 60.0,2]]
df2 = pd.DataFrame(data_list2, columns=["ID","col1", "col2", "col3", "col4", "col5", "col6", "col7"])
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 |
---|---|---|---|---|---|---|---|---|
0 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1 |
1 | 107 | name7 | address7 | F | 2000-01-07 | 140.0 | 40.0 | 1 |
2 | 108 | name8 | address8 | F | 2000-01-08 | 150.0 | 50.0 | 2 |
3 | 109 | name9 | address9 | F | 2000-01-09 | 170.0 | 60.0 | 1 |
4 | 110 | name10 | address10 | M | 2000-01-10 | 170.0 | 60.0 | 2 |
結合結果
pd.concat([df,df2],ignore_index=True)
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 |
---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 |
2 | 103 | name3 | address3 | M | 2000-01-03 | 180.0 | 70.0 | 1 |
3 | 104 | name4 | address4 | F | 2000-01-04 | 150.0 | 40.0 | 1 |
4 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2 |
5 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1 |
6 | 107 | name7 | address7 | F | 2000-01-07 | 140.0 | 40.0 | 1 |
7 | 108 | name8 | address8 | F | 2000-01-08 | 150.0 | 50.0 | 2 |
8 | 109 | name9 | address9 | F | 2000-01-09 | 170.0 | 60.0 | 1 |
9 | 110 | name10 | address10 | M | 2000-01-10 | 170.0 | 60.0 | 2 |
merge
横方向に結合する方法。
データ3
data_list = [["101","name1", "address1", "M", pd.Timestamp("20000101"), 170.0, 60.0,1],["102","name2", "address2", "F", pd.Timestamp("20000102"), 160.0, 50.0,2],["104","name4", "address4", "F", pd.Timestamp("20000104"), 150.0, 40.0,1],["105","name5", "address5", "M", pd.Timestamp("20000105"), 190.0, 80.0,2],["106","name6", "address6", "M", pd.Timestamp("20000106"), 200.0, 90.0,1],["107","name7", "address7", "F", pd.Timestamp("20000107"), 140.0, 40.0,1],["110","name10", "address10", "M", pd.Timestamp("20000110"), 170.0, 60.0,2]]
df = pd.DataFrame(data_list, columns=["ID","col1", "col2", "col3", "col4", "col5", "col6", "col7"])
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 |
---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 |
2 | 104 | name4 | address4 | F | 2000-01-04 | 150.0 | 40.0 | 1 |
3 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2 |
4 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1 |
5 | 107 | name7 | address7 | F | 2000-01-07 | 140.0 | 40.0 | 1 |
6 | 110 | name10 | address10 | M | 2000-01-10 | 170.0 | 60.0 | 2 |
データ4
data_list2 = [["101",100,10,50],["102",90,20,60],["103",80,30,70],["105",60,50,90],["106",50,60,100],["108",30,80,20],["109",20,90,30]]
df2 = pd.DataFrame(data_list2, columns=["ID","science","english","math"])
index | ID | science | english | math |
---|---|---|---|---|
0 | 101 | 100 | 10 | 50 |
1 | 102 | 90 | 20 | 60 |
2 | 103 | 80 | 30 | 70 |
3 | 105 | 60 | 50 | 90 |
4 | 106 | 50 | 60 | 100 |
5 | 108 | 30 | 80 | 20 |
6 | 109 | 20 | 90 | 30 |
INNER JOINでの結合方法
pd.merge(df,df2,how="inner",on="ID")
結合結果
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 | science | english | math |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 | 100 | 10 | 50 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 | 90 | 20 | 60 |
2 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2 | 60 | 50 | 90 |
3 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1 | 50 | 60 | 100 |
LEFT JOINでの結合方法
pd.merge(df,df2,how="left",on="ID")
結合結果
index | ID | col1 | col2 | col3 | col4 | col5 | col6 | col7 | science | english | math |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1 | 100.0 | 10.0 | 50.0 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2 | 90.0 | 20.0 | 60.0 |
2 | 104 | name4 | address4 | F | 2000-01-04 | 150.0 | 40.0 | 1 | NaN | NaN | NaN |
3 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2 | 60.0 | 50.0 | 90.0 |
4 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1 | 50.0 | 60.0 | 100.0 |
5 | 107 | name7 | address7 | F | 2000-01-07 | 140.0 | 40.0 | 1 | NaN | NaN | NaN |
6 | 110 | name10 | address10 | M2000-01-10 | 170.0 | 60.0 | 2 | NaN | NaN | NaN |
RIGHT JOINでの結合方法
pd.merge(df,df2,how="right",on="ID")
結合結果
index | col1 | col2 | col3 | col4 | col5 | col6 | col7 | science | english | math |
---|---|---|---|---|---|---|---|---|---|---|
0 | 101 | name1 | address1 | M | 2000-01-01 | 170.0 | 60.0 | 1.0 | 100 | 10 |
1 | 102 | name2 | address2 | F | 2000-01-02 | 160.0 | 50.0 | 2.0 | 90 | 20 |
2 | 105 | name5 | address5 | M | 2000-01-05 | 190.0 | 80.0 | 2.0 | 60 | 50 |
3 | 106 | name6 | address6 | M | 2000-01-06 | 200.0 | 90.0 | 1.0 | 50 | 60 |
4 | 103 | NaN | NaN | NaN | NaT | NaN | NaN | NaN | 80 | 30 |
5 | 108 | NaN | NaN | NaN | NaT | NaN | NaN | NaN | 30 | 80 |
6 | 109 | NaN | NaN | NaN | NaT | NaN | NaN | NaN | 20 | 90 |
・データの入出力
CSVデータの入出力方法
df.to_csv("foo.csv")
pd.read_csv("foo.csv")
Excelデータの入出力方法
df.to_excel("foo.xlsx", sheet_name="Sheet1")
pd.read_excel("foo.xlsx", "Sheet1", index_col=None, na_values=["NA"])
まとめ
基本的なpandasの使い方をまとめました。
pandasは他にも色々便利な機能も用意されているので、今後利用した際にまとめたいと思います。
参考資料