今回から数回にわたり、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