pandas.Series

pandas.Series

pandas.Series の構造と作成方法

 pandas の Series オブジェクト は NumPy の一次元配列に明示的なインデクス (ラベル) をマップする(割り当てる)構造体です。pandas.Series() にシーケンスまたは配列を渡すと Series オブジェクトが生成されます。

# PANDAS_SERIES

# In[1]

# NumPyとpandasをインポート
import numpy as np
import pandas as pd

# Seriesオブジェクトを生成
data = pd.Series([10, 20, 30])

print(data)
0    10
1    20
2    30
dtype: int64

 Series オブジェクトの左側の列に表示されている数字が Index オブジェクト とよばれる明示的インデクスで、index 属性にアクセスして取り出せます。

# In[2]

# dataのindex属性を取得
d_idx = data.index

print(d_idx)
RangeIndex(start=0, stop=3, step=1)

 Series オブジェクトの右側の列に並ぶ数字は NumPy の配列 (ndarray) です。values 属性にアクセスして参照できます。

# In[3]

# dataのvalues属性を取得
d_val = data.values

print(d_val)
print(type(d_val))
[10 20 30]
<class 'numpy.ndarray'>

Series のインデクス

 Indexオブジェクトは NumPy 配列の内部インデクスとは別に定義されています。デフォルト設定では 0 から始まる整数がマップされていますが、ユーザーは index 引数にシーケンスや配列を渡してインデクスを自由に設定できます。Index オブジェクトは数値に限らず、文字列など任意の型で構成できます。

# PANDAS_SERIES_INDEX

# In[1]

# 配列に文字列をマップする
data = pd.Series([10, 20, 30, 40, 50],
                 index = ["a", "b", "c", "d", "e"])

print(data)
a    10
b    20
c    30
d    40
e    50
dtype: int64

 Seriesオブジェクトの配列要素には、明示的なインデクスを使ってアクセスできます。

# In[2]

print(data["c"])
30

 NumPy の配列と同様に、Seriesオブジェクトはスライシング、マスク、ファンシーインデクスなどの機能を備えています。

# In[3]

# インデクス b から d までスライシング
print(data["b" : "d"])
b    20
c    30
d    40
dtype: int64
# In[4]

# マスク(30以上の要素をすべて取得)
print(data[data >= 30])
c    30
d    40
e    50
dtype: int64
# In[5]

# ファンシーインデクス
idx = ["c", "b", "e"]
print(data[idx])
c    30
b    20
e    50
dtype: int64

Series とディクショナリの比較

 Seriesオブジェクト は Python のディクショナリ (dictオブジェクト) に類似する構造体です。Indexオブジェクトはディクショナリの key、一次元配列はディクショナリの value と考えることができます。実際、pandas.Series() にディクショナリを渡すと そのままの形で Series オブジェクトに変換されます。

# PANDAS_SERIES_DICTIONARY

# In[1]

import numpy as np
import pandas as pd

# Python入門書の表題と価格
python_book_dict = {"かんたんPython" : 3002,
                    "Pythonスタートブック" : 2700,
                    "わかるPython" : 2570}

# 辞書をSeriesオブジェクトに変換
python_book = pd.Series(python_book_dict)

print(python_book)
かんたんPython       3002
Pythonスタートブック    2700
わかるPython        2570
dtype: int64

Seriesとスカラーの演算

 算術演算子を使って Series オブジェクトとスカラー (数値) の間で演算を実行すると、オブジェクトの中に組み込まれた NumPy の一次元配列とスカラーの間で演算が実行され、インデクスはそのまま保存されます。簡単な例を見てみましょう。最初に次のような Seriesオブジェクトを生成します。

# PANDAS_SERIES_SCALAR

# In[1]

# NumPyとpandas をインポート
import numpy as np
import pandas as pd

# Seriesオブジェクトを生成
x = pd.Series([10, 20, 30],
              index = ["a", "b", "c"])

print(x)
a    10
b    20
c    30
dtype: int64

 x + 5 は、すべての要素に 5 を加えます:

# In[2]

# すべての要素に5を加える
y = x + 5

print(y)
a    15
b    25
c    35
dtype: int64

 2 * x はすべての要素を 2 倍します:

# In[3]

# すべての要素を2倍する
z = 2*x 

print(z)
a    20
b    40
c    60
dtype: int64

 

Series とユニバーサル関数

 NumPy のユニバーサル関数 (ufunc) に Seriesオブジェクトを渡すと、インデクスをそのまま残します。

# In[4]

# すべての要素の自然対数をとる
y = np.log(x)

print(y)
a    2.302585
b    2.995732
c    3.401197
dtype: float64

Series のデータ操作

 NumPy配列と同じように、Seriesオブジェクト同士で算術演算子やメソッドを用いた演算が可能です。最初に簡単な例として、共通インデクスが割り当てられた Series 同士で足し算を実行してみます。

# PANDAS_SERIES_ADD

# In[1]

import numpy as np
import pandas as pd

# Seriesオブジェクトを生成
x = pd.Series([10, 20, 30], index=list("ABC"))
y = pd.Series([ 5, 10, 15], index=list("ABC"))

print(x + y)
A    15
B    30
C    45
dtype: int64

 今度は x のインデクスを逆順に定義し直します。

# In[2]

# xのインデクス順序を変更
x = pd.Series([10, 20, 30], index=list("BCA"))

print(x)
B    10
C    20
A    30
dtype: int64

 改めて x に y を加えてみます。

# In[3]

# Series x
# B    10
# C    20
# A    30
# dtype: int64

# Series y
# A     5
# B    10
# C    15
# dtype: int64

print(x + y)
A    35
B    20
C    35
dtype: int64

 結果を見ると、同じ明示的インデクスをもつ要素同士で足し算されていることがわかります。また、x + y のインデクスは A から順に整列しています。このように、Seriesオブジェクトは自動ソート機能を備えています。
 
 pandas はもっと複雑な演算にも対応しています。今度は互いに異なるインデクスを含む Series 同士の演算を試みます。x と y をあらためて次のように定義し直します。

# In[4]

# Seriesオブジェクトを生成
x = pd.Series([10, 20, 30], index=list("CBA"))
y = pd.Series([ 5, 10, 15], index=list("BDC"))

print(x,"\n")
print(y)
C    10
B    20
A    30
dtype: int64 

B     5
D    10
C    15
dtype: int64

 x にはインデクス "D" の要素が含まれておらず、y にはインデクス "A" の要素が含まれていません。x と y を加えると次のような結果となります。

# In[5]

# xにyを加える
print(x + y)
A     NaN
B    25.0
C    25.0
D     NaN
dtype: float64

 インデクス "A" とインデクス "D" では、要求される演算が実行できないので「欠損値」として扱われ、NaN (Not a Number : 非数) で埋められています (欠損値については、こちらの記事で詳しく解説しています)。
 
[pandas] Series のインデクス整列01
 しかし状況によっては、欠損値に NaN 以外を与えたいこともあります。たとえば、add()メソッドの引数 fill_value に 0 を渡すと、x と y にそれぞれ仮想的なインデクス "D" とインデクス "A" を付加して、要素 0 を割り当てて足し算できます。
 
[pandas] Series のインデクス整列02 fill_values

# In[6]

# x に y を加える
# 仮想インデクス "A","D"に0を割り当てて演算を実行
z = x.add(y, fill_value=0)

print(z)
A    30.0
B    25.0
C    25.0
D    10.0
dtype: float64

 Seriesオブジェクトは、他にも以下のような算術メソッドを備えています。

演算の種類 算術メソッド
加算 add()
減算 sub()
乗算 mul()
除算 div()
切り捨て除算 floordiv()
剰余 mod()
べき乗 pow()