2010-06-30 84 views
2

我有一個numpy的陣列,其看起來像選擇從numpy的陣列的每一行的隨機樣品,不含負數

>>> a 
array([[ 3. , 2. , -1. ], 
     [-1. , 0.1, 3. ], 
     [-1. , 2. , 3.5]]) 

我想選擇從隨機的每一行的值,但我想排除隨機抽樣中的-1值。

我目前做的是:

x=[] 
for i in range(a.shape[0]): 
    idx=numpy.where(a[i,:]>0)[0] 
    idxr=random.sample(idx,1)[0] 
    xi=a[i,idxr] 
    x.append(xi) 

,並得到

>>> x 
[3.0, 3.0, 2.0] 

這成爲大型陣列的速度有點慢,我想知道是否有一種方法可以有條件地選擇隨機來自原始a矩陣的值不分別處理每行。

+0

我沒有與任何NumPy的經驗,但我也能猜到樣本量生成一個隨機數比從數組中訪問數據花費的時間要長。追加到列表中也是如此。你有沒有分析你的程序,以確保你正在優化正確的事情? – torak 2010-06-30 16:24:04

+0

我已經對程序進行了剖析,'idx'和'idxr'這兩行是最慢的,每次花費的時間幾乎相等。 – fideli 2010-06-30 17:11:56

+0

您是否總是希望在每一行中具有相同數量的排除值?如果是這樣,你可以矢量化整個事情,並在沒有python循環的兩行代碼中執行它... – 2010-06-30 22:18:56

回答

3

我真的不認爲你會在Numpy中發現任何你正在打包的東西,所以我決定提供我可以想到的優化。

有幾件事可能會讓這裏變得很慢。首先,numpy.where()相當慢,因爲它必須檢查切片數組中的每個值(切片也是爲每行生成的),然後生成一組值。如果你計劃在同一個矩陣上重複執行這個過程,你可以做的最好的事情就是對每一行進行排序。然後,您只需使用二進制搜索來查找正值開始的位置,並使用隨機數字從中選擇一個值。當然,您也可以在用二進制搜索查找一次後,將正值的索引存儲起來。

如果您不打算多次完成此過程,那麼我會建議使用Cython來加速numpy.where行。 Cython將允許您不需要將行分割出來並加速整個過程。

我最後的建議是使用random.choice而非random.sample除非你真的做計劃的選擇是大於1

+0

我將在類似的,但新生成的陣列上做這個過程很多次,所以我會研究Cython。謝謝! – fideli 2010-07-01 13:42:44