2010-05-02 51 views
5

我像素合併在Python 2D陣列(由Y X)轉換成其x值(在「倉」給出)的二進制位與numpy的/ SciPy的像素合併,使用np.digitize:矢量的方法來在Python

elements_to_bins = digitize(vals, bins) 

其中「丘壑」是一個二維數組,即:

vals = array([[1, v1], [2, v2], ...]). 

elements_to_bins只是說什麼倉的每個元素落入。然後我想要做的是得到一個列表,其長度是「箱」中箱的數量,每個元素返回落入該箱的「瓦爾」的y維。我現在這樣做:

points_by_bins = [] 
for curr_bin in range(min(elements_to_bins), max(elements_to_bins) + 1): 
    curr_indx = where(elements_to_bins == curr_bin)[0] 
    curr_bin_vals = vals[:, curr_indx] 
    points_by_bins.append(curr_bin_vals) 

有沒有更優雅/更簡單的方法來做到這一點?我所需要的是列入每個bin的y值列表。

謝謝。

+0

如果其中一個答案解決了您的問題,請將其標記爲已接受(綠色複選標記)! :) – EOL 2010-05-05 09:18:50

回答

3

如果我理解正確你的問題:

vals = array([[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]]) # Example 

(x, y) = vals.T # Shortcut 
bin_limits = range(min(x)+1, max(x)+2) # Other limits could be chosen 
points_by_bin = [ [] for _ in bin_limits ] # Final result 
for (bin_num, y_value) in zip(searchsorted(bin_limits, x, "right"), y): # digitize() finds the correct bin number 
    points_by_bin[bin_num].append(y_value) 

print points_by_bin # [[10, 11], [20, 21, 22]] 

numpy的快速陣列操作searchsorted()用於最大效率。然後值逐個添加(因爲最終結果不是矩形陣列,Numpy無法幫助很大,爲此)。該解決方案應該比循環中的多個where()調用更快,這迫使Numpy多次重新讀取相同的陣列。

+1

numpy.searchsorted應該首選數字化的性能的原因:https://github.com/numpy/numpy/issues/2656 – Alleo 2014-04-03 16:13:38

+0

@Alleo:非常好的一點(目前實施'數字化()')。我更新了答案。 – EOL 2014-04-04 16:37:22

0

bin鍵只是整數,沒有binning,如你的例子?然後,你可能只是這樣做,沒有numpy的:

from collections import defaultdict 
bins = defaultdict(list) # or [ [] ...] as in EOL 

vals = [[1, 10], [1, 11], [2, 20], [2, 21], [2, 22]] # nparray.tolist() 
for nbin, val in vals: 
    bins[nbin].append(val) 

print "bins:", bins 
# defaultdict(<type 'list'>, {1: [10, 11], 2: [20, 21, 22]}) 
+0

+1:這對我來說看起來不錯,除了可能空箱不包含空列表(可以用defaultdict修復)。然而,也許原始的海報頭腦裏有更多的一般垃圾箱? – EOL 2010-05-05 09:16:21

1

這將返回IDL柱狀圖的Reverse_Indices的數據結構類似於:

ovec = np.argsort(vals) 
ivec = np.searchsorted(vals, bin_limits, sorter=ovec) 

然後落入倉#I元素的列表是

ovec[ ivec[i] : ivec[i+1] ] 

(我的快速計時測試說這是不是EOL的算法快5倍,因爲它不打擾創造不同大小的列表)