2017-09-05 116 views
0

我具有形式的Python:檢查陣列的列是邊界內,如果沒有邊界

a = np.array([[1,2],[3,4],[5,6]]) 

陣列內選擇一個隨機數,並且我有一個「結構域」或邊界,而這又是形式

b = np.array([[0, 4], [3,7]]) 

的陣列基本上我想檢查a[:,0]b的第一行內並且a[:,1]b第二行內。例如,在這個例子中a[:,0]=[1,3,5],我們可以看到,他們所有的工作,除了5是大於4.同樣a[:,1] = [2,4,6],所以我們看到,2,因爲2 < 3.

所以基本上我想0 <= a[:,0] <= 43 <= a[:,1]<=7失敗。當一個數字超出這個界限時,我想基本上用邊界內的一個隨機數代替它。

我嘗試

a[:,0][~np.logical_and(b[0][0] <= a[:,0], a[:,0] <= b[0][1])] = np.random.uniform(b[0][0], b[0][1]) 

a[:,1][~np.logical_and(b[1][0] <= a[:,1], a[:,1] <= b[1][1])] = np.random.uniform(b[1][0], b[1][1]) 

是否有更快/更好的辦法?

+0

是'了'總是COLS排序?另外,是預期的o/p:'[[1,3],[3,4],[4,6]]? – Divakar

+0

不是,應該是隨機的 –

+0

什麼是o/p?輸出? –

回答

1

方法1:這裏有一個方法 -

# Invalid mask where new values are to be put 
mask = (a < b[:,0]) | (a > b[:,1]) 

# Number of invalid ones per column of a 
count = mask.sum(0) 

# Get lengths for range limits set by b 
lens = b[:,1] - b[:,0] 

# Scale for uniform random number generation 
scale = np.repeat(lens, count) 

# Generate random numbers in [0,1) 
rand_num = np.random.rand(count.sum()) 

# Get offset for each set of random numbers. Scale and add offsets to get 
#equivalent of all the original code uniform rand number generation 
offset = np.repeat(b[:,0], count) 
put_num = rand_num*scale + offset 

# Finally make a copy as a float array and assign using invalid mask 
out = a.copy().astype(float) 
out.T[mask.T] = put_num 

採樣運行 -

In [1004]: a 
Out[1004]: 
array([[1, 2], 
     [7, 4], 
     [5, 6]]) 

In [1005]: b 
Out[1005]: 
array([[ 2, 6], 
     [ 5, 12]]) 

In [1006]: out 
Out[1006]: 
array([[ 2.9488404 , 8.97938277], 
     [ 4.51508777, 5.69467752], 
     [ 5.  , 6.  ]]) 
# limits: [2, 6]  [5, 12] 

方法2:另一種方法是將產生的縮放和抵消隨機數形狀與a相同,只需使用np.where以及無效掩碼在生成的隨機數和a之間進行選擇。實施將是一個更簡單的一個,像這樣 -

rand_nums = np.random.rand(*a.shape)*(b[:,1] - b[:,0]) + b[:,0] 
mask = (a < b[:,0]) | (a > b[:,1]) 
out = np.where(mask, rand_nums, a) 
+0

謝謝你的回答!你會說這比我的方法更快嗎? –

+0

@Euler_Salter讓我問你 - 「a」中只有兩個cols? – Divakar

+0

是的我只有兩列,但可能有很多行,當然可以超過5,但可以是任何數字,50等。 –

0
import numpy as np 
a = np.array([[1,2],[3,4],[5,6]]) 
b = np.array([[0,4], [3,7]]) 
for iter in range(np.size(a,1)): 
    index = np.where(np.logical_or(a[:,iter]<b[0,iter], a[:,iter]>b[1,iter])) 
    if len(index)!=0: 
     a[index,iter] = np.random.random_integers(b[0,iter], b[1,iter], size=[len(index),1]) 

這應該給你你需要什麼:)