Pandasの使い方について、侍ではいくつか記事を公開してきました。
これらの記事では、主にDataFrameを扱っていましたが、pandasにはこの他にもデータを扱うクラスが複数あります。
DataFrame以外でよく目にするクラスと言えば、Series型です。
この記事では
- pd.Series型とは何か
- pd.Series型の作り方
- pd.Series型の基本操作
に注目してSeries型の使い方についてまとめました!
pandasを使ったデータ解析ではよくお世話になるpd.Series、使いこなして一歩先を行くエンジニアになりましょう!
※ この記事のコードはPython 3.7, Ubuntu 18.04で動作確認しました。
Seriesとは
pd.Seriesとは、pandasのデータ型の一つです。
pd.DataFrameが2次元配列(行列)を扱っていたのに対して、pd.Seriesは一次元配列(ベクトル)を扱います。
DataFrameをスライスして一次元配列の形になったら、それもpd.Seriesになります。
多分この名前を知らない人でも、DataFrameを使っていたらお世話になっていることでしょう。
Seriesの作り方
ここからはJupyterlabやJupyter Notebookを使ってコードを実行していきます。
ここでは練習用のデータとして boston house-prices dataset を使って試してみましょう。
boston house-prices datasetは、アメリカのボストン市郊外の地域別住宅価格のまとめられたデータセットです。
主に回帰問題に用いられます。
まずはライブラリをimport。
import numpy as np import pandas as pd from sklearn import datasets
pd.Seriesにしたいデータを読み込みましょう。
boston = datasets.load_boston() boston.target
[出力結果]
array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. , 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6, 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2, 13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7, 21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9, ...<中略>... 15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7, 19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2, 29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8, 20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5, 23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])
pd.Seriesの作り方は簡単です。
最も簡単なpd.Seriesの作り方はベクトルを引数に渡すだけでOKです。
sr = pd.Series(boston.target) sr
[出力結果]
0 24.0 1 21.6 2 34.7 3 33.4 4 36.2 5 28.7 6 22.9 7 27.1 8 16.5 9 18.9 10 15.0 ... 497 18.3 498 21.2 499 17.5 500 16.8 501 22.4 502 20.6 503 23.9 504 22.0 505 11.9 Length: 506, dtype: float64
これでpd.Series型が作れました。
普通のnp.arrayとの違いは、各要素にindexが明示的についていることでしょう。
このindexはもちろん後から変更もできますし、初期化する際に指定することもできます。
pd.Series(data, index=[dataと同じ長さの配列])
このあたりはDataFrameと同じです。
また、DataFrameから一部を切り取ることでも作ることができます。
df= pd.DataFrame(boston.data) df.columns = boston.feature_names df["label"] = sr df.head()
これの一部を切り取ると以下のようにSeriesになっていることがわかります。
type(df["label"]) # out: pandas.core.series.Series
基本操作
seriesからnp.arrayを取り出す
DataFrameのときと同じように、seriesインスタンス.valuesで配列を取り出すことができます。
sr.values
[出力結果]
array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. , 18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6, 15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2, ...<中略>... 29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8, 20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5, 23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9])
インデクシング
インデクシング(要素を取り出す)の方法はnp.araryと同様です。
sr[0] # out: 24.0 sr[1:5] # out: 1 21.6 2 34.7 3 33.4 4 36.2 dtype: float64
また、indexが数字以外になっていた場合は、先頭の要素を0とした数字でのインデクシングだけでなく、辞書型のようなアクセスも可能です。
print(df.iloc[0,:]) print(type(df.iloc[0,:]))
[出力結果]
CRIM 0.00632 ZN 18.00000 INDUS 2.31000 CHAS 0.00000 NOX 0.53800 RM 6.57500 AGE 65.20000 DIS 4.09000 RAD 1.00000 TAX 296.00000 PTRATIO 15.30000 B 396.90000 LSTAT 4.98000 label 24.00000 Name: 0, dtype: float64 <class 'pandas.core.series.Series'>
df.iloc[0,:]はpd.Seriesで、尚且indexが文字列型です。
要素へアクセスしてみましょう。
df.iloc[0,:]["CRIM"], df.iloc[0,:][0] # out: (0.00632, 0.00632)
1つ目の書き方が辞書スタイル、2つ目の書き方が配列スタイルです。
どちらも同じ要素を取り出せていることがわかりますね。
代入
要素の代入も配列同様に行えます。
sr[0] = 1 sr
[出力結果]
0 1.0 1 21.6 2 34.7 3 33.4 4 36.2 5 28.7 6 22.9 7 27.1 8 16.5 9 18.9 10 15.0 以下略
スライス記法を使った代入も可能ですが、右辺と左辺が同じ要素数でないとエラーがでるので注意してください。
sr[0:3] = [0,1,2] sr
[出力結果]
0 0.0 1 1.0 2 2.0 3 33.4 4 36.2 5 28.7 6 22.9 7 27.1 8 16.5 9 18.9 10 15.0 以下略
四則演算
四則演算も可能です。
演算子を使うと要素ごとの演算になります。
df["CRIM"] + df["ZN"]
[出力結果]
0 18.00632 1 0.02731 2 0.02729 3 0.03237 4 0.06905 5 0.02985 6 12.58829 7 12.64455 8 12.71124 9 12.67004 10 12.72489 以下略
まとめ
この記事では、pandasのデータ型Seriesクラスについて紹介しました。
SeriesクラスはDataFrameよりは出番が少ないかもしれませんが、基本的にはnp.arrayのように使えて、indexをわかりやすく持つことができる便利なクラスです。
是非覚えて使いこなしてください!