2010-11-26 11 views
10

私はismemberを使って特定のMatlabコーディング "パターン"に対してNumpyの同等物を見つけるのに苦労しています。NumLab(Python)のMatlab 'ismember'に相当しますか?

残念ながら、このコードは、ほとんどの時間がMATLABスクリプトで費やされている傾向がありますので、効率的なNumpyを見つけたいと思っています。

基本パターンは、サブセットを大きなグリッドにマッピングすることから成ります。私は、並列配列として格納されているキーの値のペアのセットを持っている、私は同じ方法で格納されている大きな値のペアの大きなリストにこれらの値を挿入したい。

具体的には、毎月の時間グリッドに次のようにマッピングする四半期のGDPデータがあります。

quarters = [200712 200803 200806 200809 200812 200903]; 
gdp_q = [10.1 10.5 11.1 11.8 10.9 10.3]; 
months = 200801 : 200812; 
gdp_m = NaN(size(months)); 
[tf, loc] = ismember(quarters, months); 
gdp_m(loc(tf)) = gdp_q(tf); 

ないすべての四半期がそうTFと変数が必要とされているLOC両方ヶ月のリストに表示されていることに注意してください。

私はStackOverflowの上で同様の質問を見てきましたが、彼らはどちらかだけの純粋なPythonのソリューション(here)またはnumpyのは、その後使用されるLOC引数は(here)が返されませんを与えます。

この特定のコードパターンは繰り返し発生する傾向があり、機能のCPU時間の大部分を使い切るので、効率的なソリューションが私にとって本当に重要です。

コメントやデザインの変更も歓迎します。

+0

あなたがそれを自分で実装する場合は、次のようにします。1.オブジェクトがハッシュを取る場合、すでに数字があります。それらをソートしてバイナリ検索を使用します。 2.別のアプローチ - ハッシュマップを使用 – Mikhail

+0

私はこれを考える[アレックスMartelliによる回答](http://stackoverflow.com/questions/1273041/how-can-i-implement-matlabs-ismember-command-in-python/1273815# 1273815)はあなたが得ることができる最高です。 –

答えて

6

ヶ月がソートされている場合は、np.searchsortedを使用しています。それ以外の場合は、並べ替えた後、np.searchsorted使用:

import numpy as np 
quarters = np.array([200712, 200803, 200806, 200809, 200812, 200903]) 
months = np.arange(200801, 200813) 
loc = np.searchsorted(months, quarters) 

np.searchsortedを挿入位置を返します。あなたのデータは右の範囲でさえない可能性がある場合は、後でチェックを持っている場合があります:

valid = (quarters <= months.max()) & (quarters >= months.min()) 
loc = loc[valid] 

これはO溶液(N Nを記録)。これが実行時間に関してあなたのプログラムで依然として大きな問題であれば、O(N)となるハッシングスキームを使用してC(++)のこのサブルーチンを実行するだけでよいでしょう。もちろん)。

+0

ありがとうございます。ハッシングスキームの背後にあるアイデアを簡単に紹介できますか?私の場合、ほとんどの場合、両方のキー配列がソートされているので、両方を並行して処理するリニアO(N)スキームが機能するはずです。私は自分自身でCコードを記述することを常に躊躇しています。なぜなら、自分自身の拡張でリンクする方法を実際に調査する時間をとらなかったからです。 – snth

+0

私は「hash = dict(i、val)(enumerate(months))」の行に沿って何かを考えていましたが、結果= [jヶ月のjの場合はjのhash [j] C. STLハッシュタイプを使用できるようにするにはC++を使用します。 – luispedro

2

元のMATLABコードサンプルを再設計して、ISMEMBER関数を使用しないようにすることができると思います。これは、MATLABコードをスピードアップし、あなたはまだしたい場合は、それが簡単にPythonで再実装することがあり:

quarters = [200712 200803 200806 200809 200812 200903]; 
gdp_q = [10.1 10.5 11.1 11.8 10.9 10.3]; 

monthStart = 200801;    %# Starting month value 
monthEnd = 200812;    %# Ending month value 
nMonths = monthEnd-monthStart+1; %# Number of months 
gdp_m = NaN(1,nMonths);   %# Initialize gdp_m 

quarters = quarters-monthStart+1; %# Shift quarter values so they can be 
            %# used as indices into gdp_m 
index = (quarters >= 1) & (quarters <= nMonths); %# Logical index of quarters 
                %# within month range 
gdp_m(quarters(index)) = gdp_q(index); %# Move values from gdp_q to gdp_m 
+0

+1:ismemberは、あなたのケースでは必要ない「ユニーク」を呼び出すような、あらゆる種類の追加の処理を行います。あなたは間違いなくMatlab(またはnumpy)コードを合理化することができます。 – Jonas

関連する問題