今回はPandasのSeriesについて、その基本を動画を使って学習します。
Pandasについて
Pandasは高度なデータ構造を持ち、Pythonデータの整理や分析を簡単に行うことができます。
つまり、データ分析をより簡単に直感的に使うためのものと考えても良さそうです。
そんなことから、AIの分野ではPythonと共に頻繁に使用されるものです。
Pandasの注意点として、Numpyと同様にforループ処理を好まないところです。
Pandasのデータ構造
PandasにはSeriesとDataFrameの2種類のデータ構造があります。
- Seriesは1次元の配列のようなもの
- DataFrameはテーブル形式のデータ構造を持つ
Pandasの使い方
Pandasのインストール
Pandasのインストールはpipで行えます。
Macの場合はpip3を使う場合もあります。
Anaconda環境ではpipの代わりにcondaを使います。自分の環境に合わせてインストールしましょう。
インストール例
pip install pandas
Google ColaboはすでにPandas がインストールされています。
Pandasのインポート
通常のPandasのインポート方法は次のようにします。
as の後の省略語は一般的にpdとする場合が多いです。
import pandas as pd
Seriesもしくは、DataFrameを頻繁に使用する場合は、次のようにすると便利です。
from pandas import Series, DataFrame
Seriesとは
PandasのSeriesは1次元のNumpy配列のようなものです。
Numpy配列との違いは、配列と関連付けられたインデックスを持つことです。
Seriesを作るには、PandasのSeries関数(コンストラクター)を使います。
特にインデックスを明示的に設置しなければ、0から始まるシーケンスになります。そしてキーワード引数のindexで明示的に指定すれば好きな値をインデックスに用いることができます。
別途時系列の取り扱いの学習で説明しますが、Pandasで時系列を扱う場合、時系列オブジェクトはタイムスタンプによってインデックス付けされたSeriesです。
パラメーター
- data: 配列のような値、Iterableな値、辞書型の値、またはスカラー値
Seriesに保存されたデータが含まれます。
バージョン0.23.0で変更:データがdictの場合、Python 3.6以降では引数の順序が維持されます。 - index: 配列のようなまたはインデックス(1d)
値はハッシュ可能で、データと同じ長さでなければなりません。一意でないインデックス値を使用できます。指定しない場合、デフォルトでRangeIndex(0、1、2、…、n)になります。辞書とインデックスシーケンスの両方が使用されている場合、インデックスは辞書で見つかったキーをオーバーライドします。 - dtype: str、numpy.dtype、またはExtensionDtype、オプション
出力シリーズのデータ型。指定しない場合、これはdataから推定されます。その他の使用法については、ユーザーガイドを参照してください。 - name: str、オプション
シリーズに付ける名前。 - copy: ブール値、デフォルトはFalse
通常は入力データを参照するが、コピーして使いたい場合は、Trueにする。
Seriesデータの作成方法
インデックスなしのSeriesデータ作成
インデックスを明示的に指定しないで作成した場合、0から始まる数列がインデックスになります。
まずはNumpy配列の例
# Numpy配列の例 import numpy as np data_np = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90]) data_np
結果
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
Seriesでリストを作成すると、自動でインデックスが割り振られて**左側に表示されます**。
通常のリストやNumpy配列とここが違います。
インデックスは指定しなければ自動で0からN-1(Nはデータ数)の番号が割り振られます。
インデックスなしのSeries作成例
# インデックス指定なしのSeries sample = pd.Series([0, 10, 20, 30, 40, 50, 60, 70, 80, 90]) sample
結果
0 0
1 10
2 20
3 30
4 40
5 50
6 60
7 70
8 80
9 90
dtype: int64
インデックス指定ありのSeriesデータ作成
indexというキーワード引数で設定します。
インデックス付きのSeries作成例
# インデックス指定ありのSeries sample2 = pd.Series([0, 10, 20, 30, 40, 50, 60, 70, 80, 90], index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']) sample2
結果
a 0
b 10
c 20
d 30
e 40
f 50
g 60
h 70
i 80
j 90
dtype: int64
当然別に指定したリストをインデックスに使うことができます。
# インデックス指定ありのSeries my_index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] sample2 = pd.Series([0, 10, 20, 30, 40, 50, 60, 70, 80, 90], index=my_index) sample2
結果
a 0
b 10
c 20
d 30
e 40
f 50
g 60
h 70
i 80
j 90
dtype: int64
Pythonのtype関数で型を確認
type関数で型を確認する例
type(sample2)
結果
pandas.core.series.Series
Seriesの属性について
Seriesの属性は複数存在します。詳細はドキュメントを参考にしてください。
データとインデックスを分離
values属性とindex属性
- valuesプロパティ:Seriesがもつデータ配列を返す
- indexプロパティ:インデックスオブジェクトを返す
Seriesの値だけ取得する例
data = sample2.values print(data)
結果
array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])
Seriesのインデックスだけ取得する例
index = sample2.index print(index) 結果 Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object') <h3>1つの要素や複数の要素の指定</h3> index付きのSeriesデータの作成 obj1 = pd.Series([4, 7, -5, 3], index=['No1', 'No2', 'No3', 'No4']) obj1
結果
No1 4
No2 7
No3 -5
No4 3
dtype: int64
インデックスラベルで個別の要素を取得する方法
print(obj1['No2']) print(obj1['No4'])
結果
7
3
インデックスをリストで指定することで特定の要素を複数指定できます。
print(obj1[['No1', 'No2', 'No4']])
結果
No1 4
No2 7
No4 3
dtype: int64
次の2つのコードのように順番を入れ替えて取り出すことができます。
print(obj1[['No1', 'No4', 'No2']])
結果
No1 4
No4 3
No2 7
dtype: int64
もともと付けられているインデックス番号(0から始まるシーケンス)でも指定可能です。
print(obj1[[1, 3, 2]])
結果
No2 7
No4 3
No3 -5
dtype: int64
スライスでの範囲指定
print(obj1[1:3])
結果
No2 7
No3 -5
dtype: int64
値の変更
個別の値を呼び出して、新たな値を代入すると変更できます。
obj1['No1'] = 2 obj1
結果
No1 2
No2 7
No3 -5
No4 3
dtype: int64
複数の値の変更
代入する値をリストかタプルで渡します。
obj1[[‘No2’, ‘No3’, ‘No4’]] = 10, 11, 12 は obj1[[‘No2’, ‘No3’, ‘No4’]] = (10, 11, 12) と同等です。
複数の値を変更する例
obj1[['No2', 'No3', 'No4']] = (10, 11, 12) obj1
結果
No1 4
No2 10
No3 11
No4 12
dtype: int64
辞書をSeriesに変換できます。
Seriesは辞書に近いものです。従って辞書から簡単にSeriesに変換できます。
辞書からSeriesへ変更例
sdata = {'Apple':120, 'Orange':80, 'Banana':120, 'Grape':380} obj2 = pd.Series(sdata) obj2
結果
Apple 120
Orange 80
Banana 120
Grape 380
dtype: int64
インデックスの並び順を変更
辞書を読み込む際に、キーの並び順を変更できます。
辞書にないインデックスを指定するとNANが表示されます。
インデックス並び順変更例
sdata = {'Apple':120, 'Orange':80, 'Banana':100, 'Grape':380} name = ['Grape', 'Orange', 'Apple', 'Peach'] obj3 = pd.Series(sdata,name) obj3
結果
Grape 380.0
Orange 80.0
Apple 120.0
Peach NaN
dtype: float64
欠損値が存在するかどうか判定
- isnull():NANが True となり、それ以外が False になります。
- notnull():NANが False となり、それ以外が True になります。
Seriesの欠損値確認例
pd.isnull(obj3)
結果
Grape False
Orange False
Apple False
Peach True
dtype: bool
インデックスの置き換え
インデックスの置き換えは代入で簡単にできます。
インデックス置き換え例
obj3.index = ['No1', 'No2', 'No3', 'No4'] obj3
結果
No1 380.0
No2 80.0
No3 120.0
No4 NaN
dtype: float64
Seriesの参照とコピー
参照とコピーを確認するためにSeriesを作成
sdata = {'Apple':120, 'Orange':80, 'Banana':100, 'Grape':380} obj4 = pd.Series(sdata) obj4
結果
Apple 120
Orange 80
Banana 100
Grape 380
dtype: int64
出来上がったSeriesをさらにSeriesコンストラクタで新しいSeriesを作成し、その後新しいSeriesの値を変更して元のSeriesを確認すると参照しているためどちらも値が変更されています。
obj5 = pd.Series(obj4) obj5['Apple'] = 150 print('obj5', obj5, sep='\n') print('---------------------') print('obj4', obj4, sep='\n')
結果
obj5
Apple 150
Orange 80
Banana 100
Grape 380
dtype: int64
———————
obj4
Apple 150
Orange 80
Banana 100
Grape 380
dtype: int64
sdata = {'Apple':120, 'Orange':80, 'Banana':100, 'Grape':380} obj4 = pd.Series(sdata)
次の場合は、copy=Trueとなっているためデータはコピーされます。
そのため元データは変更されません。
obj6 = pd.Series(obj4, copy=True) obj6
結果
Apple 120
Orange 80
Banana 100
Grape 380
dtype: int64
obj6['Apple'] = 150 print('obj6', obj6, sep='\n') print('---------------------') print('obj4', obj4, sep='\n')
結果
obj6
Apple 150
Orange 80
Banana 100
Grape 380
dtype: int64
———————
obj4
Apple 120
Orange 80
Banana 100
Grape 380
dtype: int64
参考になった書籍
Pandasを使いこなすための必携の本。Pandasの作者自ら書いた本でNumpyやPandasの使い方が詳細に書かれている。
Pythonサンプルのダウンロード
ここでダウンロードする「Pandas_video_series.ipynb」ファイルは、このPandas動画で使用したものです。