2017-03-31 19 views
2

同じ量を表す2つの列のデータがあります。 1列は私の訓練データから、もう1列は私の検証データからです。pythonを使用して別の列を基準にデータ列のパーセンタイル順位を計算する方法

私が使用して効率的に学習データのパーセンタイル順位を計算する方法を知っている:

pandas.DataFrame(training_data).rank(pct = True).values 

私の質問はどのように私は効率的相対的な検証データ列のパーセンタイル順位の同様のセットを取得ことができ、ありますをトレーニングデータ列に追加しますか?つまり、検証データ列の各値について、訓練データ列のすべての値に対するパーセンタイルの順位付けを見つけるにはどうすればよいでしょうか?

私はこれやってみました:

def percentrank(input_data,comparison_data): 
    rescaled_data = np.zeros(input_data.size) 
    for idx,datum in enumerate(input_data): 
     rescaled_data[idx] =scipy.stats.percentileofscore(comparison_data,datum) 
    return rescaled_data/100 

をしかし、私はこれも正しいかどうかわからないんだけど、それは各値に対して冗長な計算をたくさんやっているので、その上に、それは信じられないほど遅いですforループ内にあります。

ご協力いただければ幸いです!

答えて

6

ここに解決策があります。 トレーニングデータをソートします。次に、検証データに対してsearchsortedを使用します。

import pandas as pd 
import numpy as np 

# Generate Dummy Data 
df_train = pd.DataFrame({'Values': 1000*np.random.rand(15712)}) 

#Sort Data 
df_train = df_train.sort_values('Values') 

# Calculating Rank and Rank_Pct for demo purposes 
#but note that it is not needed for the solution 
# The ranking of the validation data below does not depend on this 
df_train['Rank'] = df_train.rank() 
df_train['Rank_Pct']= df_train.Values.rank(pct=True) 

# Demonstrate how Rank Percentile is calculated 
# This gives the same value as .rank(pct=True) 
pct_increment = 1./len(df_train) 
df_train['Rank_Pct_Manual'] = df_train.Rank*pct_increment 

df_train.head() 

     Values Rank Rank_Pct Rank_Pct_Manual 
2724 0.006174 1.0 0.000064   0.000064 
3582 0.016264 2.0 0.000127   0.000127 
5534 0.095691 3.0 0.000191   0.000191 
944 0.141442 4.0 0.000255   0.000255 
7566 0.161766 5.0 0.000318   0.000318 

には現在、検証データのRank_Pct

# Generate Dummy Validation Data 
df_validation = pd.DataFrame({'Values': 1000*np.random.rand(1000)}) 

# Note searchsorted returns array index. 
# In sorted list rank is the same as the array index +1 
df_validation['Rank_Pct'] = (1 + df_train.Values.searchsorted(df_validation.Values))*pct_increment 

を取得するためにsearchsorted使用し、最終的なdf_validationのデータフレームの最初の数行です:

print df_validation.head() 
     Values Rank_Pct 
0 307.378334 0.304290 
1 744.247034 0.744208 
2 669.223821 0.670825 
3 149.797030 0.145621 
4 317.742713 0.314218 
+0

ありがとう、それは非常に巧妙なトリックです! – Doodles

1

は、上記の素敵なソリューションへの小さな改善がにあります左から検索して右から検索した位置の平均:

df_validation['Rank_Pct'] = (0.5 + 0.5*df_train.Values.searchsorted(df_validation.Values, side='left') + 0.5*df_train.Values.searchsorted(df_validation.Values, side='right'))*pct_increment 

この変更は、値が複数回発生する場合に重要です。 [1,2,2,2,4]で2を検索すると、左から検索すると1が得られ、右から検索すると3が得られます。この2つを平均すると、パンダのランク(pct = True)ルーチン。

関連する問題