意味悲鳴

PythonとかUnityとか.技術ブログでしたが,研究ブログにシフトしました.

Python3で配列の要素についてランキングを作って云々する

http://pythonhosted.org/ranking/ これ使う,以上. でも良かった気がするんですけど,だいぶ前のものでメンテもされていないっぽいので,今回はscipyのrankdataを使って,配列のランキングを拾ってきて,n位の要素を取得するみたいなことをしてみたいと思います.素人だからあんまりまともに取り合わないこと.

In[2]: from scipy.stats import rankdata
In[3]: import numpy as np
In[4]: array = np.array([8,6,9,4,5]) # これ使う

早速rankdataを使ってみる.

In[5]: rank = rankdata(array)
In[6]: rank
Out[6]: 
array([ 4.,  3.,  5.,  1.,  2.])

ここでお気づきの方もいるかもしれませんが,順位が照準になっています.しかもこれ,オプションとかで指定できません.ぐぬぬって感じです.

もうこれだったら普通にsorted使ってソートしてインデックス指定すればそれで終わりで良くないっすか?という気分になると思うんです.配列の要素がtupleのときとか対応できないっぽいし.私も今そう思っています.

が,一応これを使うメリットがまったくないわけでもなくて,リスト内に同じ要素が存在していた時,それをうまい具合に順位付けしてくれます.

ドキュメントから引用してくると,

>>> from scipy.stats import rankdata
>>> rankdata([0, 2, 3, 2])
array([ 1. ,  2.5,  4. ,  2.5])
>>> rankdata([0, 2, 3, 2], method='min')
array([ 1.,  2.,  4.,  2.])
>>> rankdata([0, 2, 3, 2], method='max')
array([ 1.,  3.,  4.,  3.])
>>> rankdata([0, 2, 3, 2], method='dense')
array([ 1.,  2.,  3.,  2.])
>>> rankdata([0, 2, 3, 2], method='ordinal')
array([ 1.,  2.,  4.,  3.])

こんな感じで,同じ値があったら上の順位をつけるか下の順位をつけるか,それとも同じ値をつけずに順位付けするかを指定できます.これを自前で実装するのはそれなりに面倒だし,そういう意味では良いのかも?今回は使っていませんが.

で,実際使用する用途としては多分こんな感じ.

In[9]: np.where(rank == 5)
Out[9]: 
(array([2], dtype=int64),)
In[10]: array[np.where(rank == 5)]
Out[10]: 
array([9])

こんな感じでした.ちなみにPythonの普通のlistにnp.where()をぶっこむとTupleだからインデックスちゃんと指定しろって怒られるのでご注意ください.

中々使う場面無いと思うんだけど(上位n位全部欲しいとかばっかりだろうし),任意でどこが見たい!という時は便利なのでは.