今回から数回にわたり、pandasのシリーズやデータフレームの保持するデータへのアクセス、操作をする基本的な方法を紹介する。

インデックスを再定義するreindexメソッド

reindexメソッドは、シリーズやデータフレームのインデックスとデータの関連付けを保持しながら、インデックス名(行列名)を再定義し新しいオブジェクトトを作成することができる。

import pandas as pd
import numpy as np

series = pd.Series([1.5, 2.3, 3.1, 4.9], index=['d', 'b', 'a', 'c'])
# d    1.5
# b    2.3
# a    3.1
# c    4.9
# dtype: float64

series2 = series.reindex(['a', 'b', 'c', 'd', 'e'])
# a    3.1
# b    2.3
# c    4.9
# d    1.5
# e    NaN
# dtype: float64

df = pd.DataFrame(np.arange(15).reshape(3, 5), index=['b', 'a', 'c'], columns=['d', 'b', 'e', 'a', 'c'])
#     d   b   e   a   c
# b   0   1   2   3   4
# a   5   6   7   8   9
# c  10  11  12  13  14

df2 = df.reindex(['a', 'b', 'c'], axis=0)
#     d   b   e   a   c
# a   5   6   7   8   9
# b   0   1   2   3   4
# c  10  11  12  13  14

df2 = df2.reindex(['a', 'b', 'c', 'd', 'e'], axis=1)
#     a   b   c   d   e
# a   8   6   9   5   7
# b   3   1   4   0   2
# c  13  11  14  10  12

データフレームのreindexメソッドの場合、axisに軸を指定することで、再インデックスの対象を任意で選択できる。

methodオプションを使って穴埋めをする例

インデックスが一部欠損しているようなデータを扱う場合、methodオプションを使って穴埋めをすることもできる。
これは時系列データなどで効果を発揮するだろう。

methodオプションにffillを指定すると、直前の値をデータの補完に使う。

import pandas as pd
import numpy as np

series = pd.Series(['a', 'b', 'c'], index=[0, 3, 8])
# 0    a
# 3    b
# 8    c
# dtype: object

series.reindex(range(10), method='ffill')
# 0    a
# 1    a
# 2    a
# 3    b
# 4    b
# 5    b
# 6    b
# 7    b
# 8    c
# 9    c
# dtype: object

bfillは、ffillと逆の補完をおこなう。
そのためインデックス9は、後ろの値が存在しないため欠損値が代入される。

series.reindex(range(10), method='bfill')
# 0      a
# 1      b
# 2      b
# 3      b
# 4      c
# 5      c
# 6      c
# 7      c
# 8      c
# 9    NaN
# dtype: object

欠損値を出したくなければ、fill_valueオプションに任意の値を指定すれば、その値が欠損値の代わりに代入される。

series.reindex(range(10), method='bfill', fill_value='test')

nearestは最も近い位置にある値を代入する。

series.reindex(range(10), method='nearest')
# 0    a
# 1    a
# 2    b
# 3    b
# 4    b
# 5    b
# 6    c
# 7    c
# 8    c
# 9    c
# dtype: object

特定の軸から要素を削除するdropメソッド

dropメソッドは引数に指定したインデックスの要素を削除する。
この時、削除後のオブジェクトのコピーが作成されるため、dropメソッドを実行した元のオブジェクトには影響はない。

import pandas as pd
import numpy as np

series = pd.Series(np.arange(5.), index=['a', 'b', 'c', 'd', 'e'])
# a    0.0
# b    1.0
# c    2.0
# d    3.0
# e    4.0
# dtype: float64

series2 = series.drop('b')
print(series)
# a    0.0
# b    1.0
# c    2.0
# d    3.0
# e    4.0
# dtype: float64
    
print(series2)
# a    0.0
# c    2.0
# d    3.0
# e    4.0
# dtype: float64

データフレームに対してdropメソッドを適用する場合、削除対象の軸を指定することができる。

import pandas as pd
import numpy as np

df = pd.DataFrame(np.arange(15).reshape(3, 5), index=['a', 'b', 'c'], columns=['a', 'b', 'c', 'd', 'e'])
print(df)
#     a   b   c   d   e
# a   0   1   2   3   4
# b   5   6   7   8   9
# c  10  11  12  13  14

df2 = df.drop('a') # 軸を指定しないと行インデックスが削除される
print(df2)
#     a   b   c   d   e
# b   5   6   7   8   9
# c  10  11  12  13  14

df2 = df.drop('a', axis=1) # axisに1を指定すると列インデックスが削除される
print(df2)
#     b   c   d   e
# a   1   2   3   4
# b   6   7   8   9
# c  11  12  13  14

元のオブジェクトを更新するinplaceオプション

dropで直接元のオブジェクトを更新したい場合は、inplaceオプションにTrueを与えると良い。
ただし、削除したデータは完全に消えてしまうので扱いには注意が必要だ。

df.drop('a', inplace=True)
print(df)
#     a   b   c   d   e
# b   5   6   7   8   9
# c  10  11  12  13  14