2017-11-26 12 views
0

観測時間の配列がtsであり、それぞれが観測値の一部に対応しているとします(vs)。観測時間は、経過時間の数(ゼロから始まる)とみなされ、重複を含むことができる。一意の観測時間あたりの最大観測値に対応する指標を探したいと思います。 私は数ヶ月前に値unlike a similar questionの値とは対照的に指数を求めています。このように、私はさまざまな配列に同じインデックスを適用できます。以下にサンプルデータセットを示します。これは、もっと大きなデータセットのコードを適合させるために使用したいものです。配列Bの一意の値に対応する配列Aのすべての最大値のインデックスを取得する方法は?

import numpy as np 
ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10]) 
vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900]) 

現時点でのアプローチは、値の配列を重複しない時点で分割することです。

condition = np.where(np.diff(ts) != 0)[0]+1 
ts_spl = np.split(ts, condition) 
vs_spl = np.split(vs, condition) 

print(ts_spl) 
>> [array([0, 0]), array([1]), array([2]), array([3, 3, 3]), array([4, 4]), array([5]), array([6]), array([7]), array([8, 8]), array([9]), array([10])] 

print(vs_spl) 
>> [array([500, 600]), array([550]), array([700]), array([500, 500, 450]), array([800, 900]), array([700]), array([600]), array([850]), array([850, 900]), array([900]), array([900])] 

この場合、重複した回数の重複値をカウントする必要があります。この例で考えると、返されたインデックスは次のようになります。

[1, 2, 3, 4, 5, 8, 9, 10, 11, 13, 14, 15] 
# indices = 4,5,6 correspond to values = 500, 500, 450 ==> count indices 4,5 
# I might modify this part of the algorithm to return either 4 or 5 instead of 4,5 at some future time 

私はまだ私の目的のために、このアルゴリズムを適応することができていないけど、私はvs_splで各以前に分割配列のサイズを利用することが可能でなければならないと思いますインデックスカウンタを保持する。このアプローチは、大きなデータセット(パディング前に配列あたり10,000個の要素、パディング後に配列あたり70,000個の要素)に対して実行可能ですか?もしそうなら、どうすればそれを適応させることができますか?そうでない場合は、ここで役に立つ他のアプローチは何ですか?

答えて

1

70,000はそれほど大きくないので、実現可能であるはずです。しかし、分割を避け、関連するufuncのメソッドを使用する方が速いです。 reduceatは、チャンクに適用される縮小と似ていますが、チャンクを提供する必要はありません。reduceatに、それらを取得するためのカット先を教えてください。たとえば、like so

import numpy as np 


N = 10**6 
ts = np.cumsum(np.random.rand(N) < 0.1) 
vs = 50*np.random.randint(10, 20, (N,)) 

#ts = np.array([0, 0, 1, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10]) 
#vs = np.array([500, 600, 550, 700, 500, 500, 450, 800, 900, 700, 600, 850, 850, 900, 900, 900]) 


# flatnonzero is a bit faster than where 
condition = np.r_[0, np.flatnonzero(np.diff(ts)) + 1, len(ts)] 
sizes = np.diff(condition) 
maxima = np.repeat(np.maximum.reduceat(vs, condition[:-1]), sizes) 
maxat = maxima == vs 
indices = np.flatnonzero(maxat) 
# if you want to know how many maxima at each hour 
nmax = np.add.reduceat(maxat, condition[:-1]) 
+0

現在モバイル版です。私は約1時間でこれを試して遊ぶことができます。ありがとう! – mikey

+0

私は 'condition = np.r_ [0、np.flatnonzero(np.diff(ts))+ 1、len(ts)]'の行を除いてすべてを追うと思います。私の理解では、 'np.flatnonzero'は、ゼロではない値に対して時系列的にインデックスを返します。これは連続した観測時間をチェックします。 '.reduceat'に関するあなたのヒントは参考になりました。ドキュメントから、 'np.r_'が配列を構築することができますが、この行でその使い方を説明できますか? – mikey

+1

'flatnonzero'はコード内の' where'とまったく同じです。ベクトルとスカラーに適用された 'r_'はそれらを連結するだけなので、この場合は左にゼロを、右に長さを加えます。そうすることで、私たちは内側の境界だけでなく外側の境界も持っています。これは、例えば、次の行で行うようにチャンクのサイズを計算する場合などに便利です。 –

関連する問題