pandas.Seriesのインデックスと値を入れ替え(スワップ)
pandas.Series
のインデックス(ラベル)と値を入れ替える(スワップする)方法を説明する。
以下のpandas.Series
を例とする。timeitモジュールは処理速度計測のためにインポートしている。
import pandas as pd
import timeit
s = pd.Series(['a', 'b', 'c', 'd', 'e'])
print(s)
# 0 a
# 1 b
# 2 c
# 3 d
# 4 e
# dtype: object
以下の内容について説明する。
- コンストラクタにインデックスと値を入れ替えて指定
values
属性を使う場合と使わない場合の速度比較
コンストラクタにインデックスと値を入れ替えて指定
pandas.Series
にインデックスと値を入れ替えるメソッドはないので、コンストラクタpandas.Series()
の第一引数data
と第二引数index
にそれぞれ元のpandas.Series
のインデックスと値を指定して新たなpandas.Series
を生成する。
s_swap = pd.Series(s.index.values, s.values)
print(s_swap)
# a 0
# b 1
# c 2
# d 3
# e 4
# dtype: int64
ここではpandas.Series
およびそのindex
のvalues
属性(NumPy配列numpy.ndarray
)を使っている。
print(s.values)
# ['a' 'b' 'c' 'd' 'e']
print(type(s.values))
# <class 'numpy.ndarray'>
print(s.index.values)
# [0 1 2 3 4]
print(type(s.index.values))
# <class 'numpy.ndarray'>
values
属性を使わずにそのまま指定しても同じ結果が得られるが、values
属性を使ったほうが多少速い(後述)。
s_swap = pd.Series(s.index, s)
print(s_swap)
# a 0
# b 1
# c 2
# d 3
# e 4
# dtype: int64
values属性を使う場合と使わない場合の速度比較
values
属性を使う場合と使わない場合の速度をtimeitモジュールを使って比較する。
以下のようにvalues
属性を使ったほうが速い。
loop = 10000
result = timeit.timeit(lambda: pd.Series(s.index.values, s.values), number=loop)
print(result / loop)
# 8.694580160081386e-05
result = timeit.timeit(lambda: pd.Series(s.index, s), number=loop)
print(result / loop)
# 0.00010916587258689105
元のpandas.Series
のサイズが大きくても同じ。
s_large = pd.concat([s] * 100000)
print(len(s_large))
# 500000
loop = 100
result = timeit.timeit(lambda: pd.Series(s_large.index.values, s_large.values), number=loop)
print(result / loop)
# 0.005923357829451561
result = timeit.timeit(lambda: pd.Series(s_large.index, s_large), number=loop)
print(result / loop)
# 0.006492725329007953
とはいえ、よっぽど巨大なpandas.Series
でない限りそんなに時間がかかるわけでもないので、values
属性を使っても使わなくてもどっちでもいいかもしれない。