2015-07-10 92 views
2

我有一個程序需要一些大的NumPy數組,並且基於某些外部數據,通過向隨機選擇的單元格中添加一個來增加它們,直到數組的總和等於外部數據爲止。簡化和更小的版本是這樣的:在NumPy數組中隨機增長值

import numpy as np 
my_array = np.random.random_integers(0, 100, [100, 100]) 
## Just creating a sample version of the array, then getting it's sum: 
np.sum(my_array) 
499097 

所以,假如我想,直到其總和爲100萬增長了陣列,而且我想通過不斷地隨機細胞,加入1至,直到我們這樣做打的總和,我做的是這樣的:

diff = 1000000 - np.sum(my_array) 
counter = 0 
while counter < diff: 
    row = random.randrange(0,99) 
    col = random.randrange(0,99) 
    coordinate = [row, col] 
    my_array[coord] += 1 
    counter += 1 

當行/列結合起來,返回數組中隨機單元格,然後該單元由1土生土長的IT重複,直到次數由它將1加入隨機單元格==原始數組的總和與目標總和(1,000,000)之間的差值。

但是,當我運行此檢查後的結果 - 總是總是關閉。在與上述相同的號碼運行它後,這種情況下:

np.sum(my_array) 
99667203 

我無法弄清楚什麼是佔這個巨大的差異。是否有更多pythonic的方式去做這件事?

回答

0

my_array[coord]替換爲my_array[row][col]。您的方法選擇了兩個隨機整數,並將1添加到對應於這兩個整數的行中的每個條目。

基本上你對numpy索引數組有些小誤解。

編輯:爲了更清楚。 發佈的代碼選擇了兩個數字,比如30和45,並添加1〜30行的所有100個條目和行45

的所有100個條目從這個你所期望的總和是100,679,697 = 200*(1,000,000 - 499,097) + 499,097

然而,當隨機整數是相同的(比如45和45)時,第45列中的每個入口只增加1個,而不是2,因此在這種情況下,總和僅跳過100.

+2

這應該是'my_array [row,col]'。 'my_array [row] [col]'會起作用,但效率不高。 –

1

my_array[coordinate]不會做你所做的期望。它將選擇多行並將1添加到所有這些條目中。您可以簡單地使用my_array[row, col]

你可以簡單地寫類似:

for _ in range(1000000 - np.sum(my_array)): 
    my_array[random.randrange(0, 99), random.randrange(0, 99)] += 1 

(或xrange代替range如果使用Python 2.x的)

+0

@WarrenWeckesser:謝謝,糾正。我實際上是在我的例子中編寫的,但由於某種原因,並沒有在第一個例子中。 – grovesNL

0

與原有方法的問題是,你有你的索引數組列表,它被解釋爲行維度中的一系列索引,而不是作爲行/列維度中的單獨索引(see here)。 嘗試通過代替列表的元組:

coord = row, col 
my_array[coord] += 1 

快得多的方法是找到的總和超過所述輸入陣列和所述目標值之間的差,然後生成包含相同編號的數組的隨機索引到陣列和遞增它們全部在一個去,這樣就避免了在Python循環:

import numpy as np 

def grow_to_target(A, target=1000000, inplace=False): 

    if not inplace: 
     A = A.copy() 

    # how many times do we need to increment A? 
    n = target - A.sum() 

    # pick n random indices into the flattened array 
    idx = np.random.random_integers(0, A.size - 1, n) 

    # how many times did we sample each unique index? 
    uidx, counts = np.unique(idx, return_counts=True) 

    # increment the array counts times at each unique index 
    A.flat[uidx] += counts 

    return A 

例如:

a = np.zeros((100, 100), dtype=np.int) 

b = grow_to_target(a) 
print(b.sum()) 
# 1000000 

%timeit grow_to_target(a) 
# 10 loops, best of 3: 91.5 ms per loop