pandasの使い方(Series編)

pandasのSeriesの使い方のメモです。

pandas

pandasは高性能なデータ構造とデータ分析を提供するライブラリです。

インストール

pipでインストールします。

# pip install pandas

IPythonで使ってみます。

Series

Seriesは1次元のndarrayにインデックスというラベルが付いたものです。

SeriesとDataFrameを直接名前指定で使えるようにインポートして使います。
pandasはpdという省略名で使うのが通例です。

In [108]: from pandas import Series, DataFrame

In [109]: import pandas as pd

Seriesの生成。
配列を指定して生成。
左側にインデックス、右側に要素が表示される。

In [3]: s = Series([1, 2, 3, -1, 10])

In [4]: s
Out[4]:
0     1
1     2
2     3
3    -1
4    10
dtype: int64

valuesで要素の配列を出力。

In [5]: s.values
Out[5]: array([ 1,  2,  3, -1, 10])

indexでインデックスオブジェクトを出力。

In [6]: s.index
Out[6]: Int64Index([0, 1, 2, 3, 4], dtype='int64')

インデックスを指定して生成。

In [7]: s2 = Series([1, 2, 3, -1, 10], index=['a', 'b', 'c', 'd', 'e'])

In [8]: s2
Out[8]:
a     1
b     2
c     3
d    -1
e    10
dtype: int64

In [9]: s2.index
Out[9]: Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

インデックスを指定して要素を参照。

In [10]: s2['a']
Out[10]: 1

In [11]: s2['e']
Out[11]: 10

In [14]: s2[['d', 'c', 'b', 'a']]
Out[14]:
d   -1
c    3
b    2
a    1
dtype: int64

In [4]: s2[1]
Out[4]: 2

In [6]: s2[2:4]
Out[6]:
c    3
d   -1
dtype: int64

インデックスを指定して要素を更新。

In [12]: s2['e'] = 999

In [13]: s2['e']
Out[13]: 999

In [15]: s2
Out[15]:
a      1
b      2
c      3
d     -1
e    999
dtype: int64

In [8]: s2['b':'c'] = 99

In [9]: s2
Out[9]:
a      1
b     99
c     99
d     -1
e    999
dtype: int64

インデックスを指定して要素の削除。

In [5]: s = Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])

In [6]: new_s = s.drop('b')

In [7]: new_s
Out[7]:
a    0
c    2
d    3
e    4
dtype: float64

In [9]: s
Out[9]:
a    0
b    1
c    2
d    3
e    4
dtype: float64

式によるフィルタリング

In [16]: s2[s2 > 0]
Out[16]:
a      1
b      2
c      3
e    999
dtype: int64

各要素への演算。

In [17]: s2 * 100
Out[17]:
a      100
b      200
c      300
d     -100
e    99900
dtype: int64

In [20]: np.exp(s2)
Out[20]:
a     2.718282
b     7.389056
c    20.085537
d     0.367879
e          inf
dtype: float64

ディクショナリの様にinで要素の存在を確認。

In [21]: 'a' in s2
Out[21]: True

In [22]: 'f' in s2
Out[22]: False

Seriesのindexはインデックスオブジェクトというオブジェクトで、
軸のメタデータを保持している。

In [47]: obj = Series(range(3), index=['a', 'b', 'c'])

In [48]: index = obj.index

In [49]: index
Out[49]: Index(['a', 'b', 'c'], dtype='object')

In [50]: index[1:]
Out[50]: Index(['b', 'c'], dtype='object')

インデックスオブジェクトはイミュータブルなので変更不可。

In [51]: index[1] = 'd'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-51-676fdeb26a68> in <module>()
----> 1 index[1] = 'd'

/root/.pyenv/versions/3.5.1/lib/python3.5/site-packages/pandas/core/index.py in __setitem__(self, key, value)
   1128
   1129     def __setitem__(self, key, value):
-> 1130         raise TypeError("Index does not support mutable operations")
   1131
   1132     def __getitem__(self, key):

TypeError: Index does not support mutable operations

インデックスオブジェクトの生成。

In [52]: index = pd.Index(np.arange(3))

In [53]: obj2 = Series([1, 2, 3], index=index)

In [54]: obj2
Out[54]:
0    1
1    2
2    3
dtype: int64

In [55]: obj2.index is index
Out[55]: True

Seriesのreindex()で再インデックス付けが可能。
存在しないインデックス値の場合、NaNが設定される。

In [60]: o = Series([1, 2, 3, 10], index=['b', 'd', 'c', 'a'])

In [61]: o
Out[61]:
b     1
d     2
c     3
a    10
dtype: int64

In [62]: o2 = o.reindex(['a', 'b', 'c', 'd', 'e'])

In [63]: o2
Out[63]:
a    10
b     1
c     3
d     2
e   NaN
dtype: float64

fill_valueを指定することで、欠損値の値を変更可能。

In [64]: o.reindex(['a', 'b', 'c', 'd', 'e'], fill_value=0)
Out[64]:
a    10
b     1
c     3
d     2
e     0
dtype: int64

methodにffillを指定すると欠損値が前の値で穴埋めされる。

In [65]: o3 = Series(['AAA', 'BBB', 'CCC'], index=[0, 2, 4])

In [66]: o3
Out[66]:
0    AAA
2    BBB
4    CCC
dtype: object

In [67]: o3.reindex(range(6), method='ffill')
Out[67]:
0    AAA
1    AAA
2    BBB
3    BBB
4    CCC
5    CCC
dtype: object

methodにbfillを指定すると欠損値が後の値で穴埋めされる。

In [68]: o3.reindex(range(6), method='bfill')
Out[68]:
0    AAA
1    BBB
2    BBB
3    CCC
4    CCC
5    NaN
dtype: object

ディクショナリからSeriesを生成。

In [23]: dict = {'aaa': 1000, 'bbb': 2000, 'ccc': 3000, 'ddd': 9999}

In [24]: s3 = Series(dict)

In [25]: s3
Out[25]:
aaa    1000
bbb    2000
ccc    3000
ddd    9999
dtype: int64

ディクショナリとインデックスの配列を渡した場合、
インデックスの配列が優先される。
zzzはディクショナリに存在しないため、NaNとなる。

In [26]: keys = ['aaa', 'bbb', 'ccc', 'zzz']

In [28]: s4 = Series(dict, index=keys)

In [29]: s4
Out[29]:
aaa    1000
bbb    2000
ccc    3000
zzz     NaN
dtype: float64

isnull()とnotnull()で欠損値(NaN)を判定。

In [30]: pd.isnull(s4)
Out[30]:
aaa    False
bbb    False
ccc    False
zzz     True
dtype: bool

In [31]: pd.notnull(s4)
Out[31]:
aaa     True
bbb     True
ccc     True
zzz    False
dtype: bool

Seriesのメソッドとしても使用可能。

In [32]: s4.isnull()
Out[32]:
aaa    False
bbb    False
ccc    False
zzz     True
dtype: bool

Series同士の演算はインデックス値に基づき、計算される。

In [33]: s3
Out[33]:
aaa    1000
bbb    2000
ccc    3000
ddd    9999
dtype: int64

In [34]: s4
Out[34]:
aaa    1000
bbb    2000
ccc    3000
zzz     NaN
dtype: float64

In [35]: s3 + s4
Out[35]:
aaa    2000
bbb    4000
ccc    6000
ddd     NaN
zzz     NaN
dtype: float64

Seriesのname属性と、インデックスのname属性を設定。

In [37]: s4.name = 'chars_value'

In [40]: s4.index.name = 'alphabets'

In [41]: s4
Out[41]:
alphabets
aaa    1000
bbb    2000
ccc    3000
zzz     NaN
Name: chars_value, dtype: float64

終わり。


【参考】
Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理