2016-07-26 4 views
3

2列目に1列に2つの値の範囲を二分し、最小値を取得し、言う:私は使用していますは、だから私は、整数の2列numpyの配列を持っている

tarray = array([[ 368, 322], 
     [ 433, 420], 
     [ 451, 412], 
     [ 480, 440], 
     [ 517, 475], 
     [ 541, 503], 
     [ 578, 537], 
     [ 607, 567], 
     [ 637, 599], 
     [ 666, 628], 
     [ 696, 660], 
     [ 726, 687], 
     [ 756, 717], 
     [ 785, 747], 
     [ 815, 779], 
     [ 845, 807], 
     [ 874, 837], 
     [ 905, 867], 
     [ 934, 898], 
     [ 969, 928], 
     [ 994, 957], 
     [1027, 987], 
     [1057, 1017], 
     [1086, 1047], 
     [1117, 1079], 
     [1148, 1109], 
     [1177, 1137], 
     [1213, 1167], 
     [1237, 1197], 
     [1273, 1227], 
     [1299, 1261], 
     [1333, 1287], 
     [1357, 1317], 
     [1393, 1347], 
     [1416, 1377]]) 

がにnp.searchsorted列0に値の下限と上限を二分する、すなわち、例えば241,361の両方が配列に二等分することができる。

ranges = [array([241, 290, 350, 420, 540, 660, 780, 900]), 
array([ 361, 410, 470, 540, 660, 780, 900, 1020])] 

、例えば:np.searchsorted:

これは、次いで、その結果(TARRAYの[0]、の範囲である)2つの得られた配列の各位置の範囲である

array([[ 0, 0, 0, 1, 5, 9, 13, 17], 
     [ 0, 1, 3, 5, 9, 13, 17, 21]]) 

値。私がしたいことは、得られたスライスの列1に最小値の位置を得ることです。 (searchsortedの結果は、2列配列「F」である場合)など、ここで私はイテレーションを経て、Pythonで簡単に何を意味するかです:

f = array([[ 0, 0, 0, 1, 5, 9, 13, 17], 
     [ 0, 1, 3, 5, 9, 13, 17, 21]]) 

for i,(x,y) in enumerate(zip(*f)): 
    if y - x: 
     print ranges[1][i], tarray[x:y] 

結果は次のとおりです。

410 [[368 322]] 
470 [[368 322] 
[433 420] 
[451 412]] 
540 [[433 420] 
[451 412] 
[480 440] 
[517 475]] 
660 [[541 503] 
[578 537] 
[607 567] 
[637 599]] 
780 [[666 628] 
[696 660] 
[726 687] 
[756 717]] 
900 [[785 747] 
[815 779] 
[845 807] 
[874 837]] 
1020 [[905 867] 
[934 898] 
[969 928] 
[994 957]] 

私が欲しいものを説明します:私は列1

e.g 540 [[433 420] 
[451 412] 
[480 440] 
[517 475]] 

で最小値を持つ行が、私は最終的な結果は、([451 412]のように)412

になりたいたいスライスの範囲内

例えば

for i,(x,y) in enumerate(zip(*f)): 
    if y - x: 
     print ranges[1][i], tarray[:,1:2][x:y].min() 

410 322 
470 322 
540 412 
660 503 
780 628 
900 747 
1020 867 

は基本的に私はこれがそう、私は戻って1つの配列を取得することができvectorise、それは私のニーズのための非パフォーマンスであるとして反復する必要はありませんしたいと思います。列0の2分の1の範囲の値に対して、列1に最小値を設定します。

私は明確であることを望みます!

答えて

1

これはnumpy_indexedパッケージ(免責事項:私はその作者午前):使用して、あなたの意図した目標を達成するために表示されます

import numpy_indexed as npi 
# to vectorize the concatenation of the slice ranges, we construct all indices implied in the slicing 
counts = f[1] - f[0] 
idx = np.ones(counts.sum(), dtype=np.int) 
idx[np.cumsum(counts)[:-1]] -= counts[:-1] 
tidx = np.cumsum(idx) - 1 + np.repeat(f[0], counts) 

# combined with a unique label tagging the output of each slice range, this allows us to use grouping to find the minimum in each group 
label = np.repeat(np.arange(len(f.T)), counts) 
subtarray = tarray[tidx] 
ridx, sidx = npi.group_by(label).argmin(subtarray[:, 0]) 

print(ranges[1][ridx]) 
print(subtarray[sidx, 1]) 
+0

良い仕事を!私は同じ行に沿って考えていたし、パンダgroupbyを使うことができると思った。 – Divakar

+0

ええ、興味深い質問でした。一連のスライスからインデックスを構成することは、私が直感したよりもやりにくいものでした。私はまだもっと簡単なものが欠けているような気がします。 –

+1

うん、あなたは 'id_arr = np.ones(counts.sum()、dtype = int)のような何かをすることができます。 id_arr [np.append(0、counts [: - 1] .cumsum())] = np.append(0、f [0,1:] - f [1、: - 1] +1) ' 'tidx'は' id_arr.cumsum() - 1'です。無効なものを除外した場合(例: 'f'からの最初のエントリは' tidx'を得るために '-1'を避けるでしょう。私は、np.repeatを回避する唯一のメリットがあると思います。また、パフォーマンスを向上させるには、2つのステップに分割して最初のエントリと残りのエントリに別々に追加およびインデックス付けすることを避けてください。 – Divakar

関連する問題