![](/img/trans.png)
[英]Row-wise replacement of numpy array with values of another numpy array
[英]How to randomly assign values row-wise in a numpy array
我的Google Fu使我失敗了! 我有一個10x10的numpy數組,初始化為0
,如下所示:
arr2d = np.zeros((10,10))
對於arr2d
每一行,我想將3個隨機列分配給1
。 我可以使用如下循環來做到這一點:
for row in arr2d:
rand_cols = np.random.randint(0,9,3)
row[rand_cols] = 1
輸出:
array([[ 0., 0., 0., 0., 0., 0., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 1., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 0., 1., 1., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.],
[ 1., 0., 0., 1., 1., 0., 0., 0., 0., 0.],
[ 1., 0., 1., 1., 0., 0., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0., 0., 1., 0., 1., 0.],
[ 0., 0., 1., 0., 1., 0., 0., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 0., 1., 1., 0., 0.],
[ 0., 1., 0., 0., 1., 0., 0., 1., 0., 0.]])
有沒有一種方法可以利用numpy或數組索引/切片以更pythonic /優雅的方式(最好在1或2行代碼中)獲得相同的結果?
一旦你的arr2d
與初始化arr2d = np.zeros((10,10))
您可以使用矢量方法有two-liner
像這樣-
# Generate random unique 3 column indices for 10 rows
idx = np.random.rand(10,10).argsort(1)[:,:3]
# Assign them into initialized array
arr2d[np.arange(10)[:,None],idx] = 1
或者,如果您喜歡那樣的話,可以抽成一排的所有物品:
arr2d[np.arange(10)[:,None],np.random.rand(10,10).argsort(1)[:,:3]] = 1
樣品運行-
In [11]: arr2d = np.zeros((10,10)) # Initialize array
In [12]: idx = np.random.rand(10,10).argsort(1)[:,:3]
In [13]: arr2d[np.arange(10)[:,None],idx] = 1
In [14]: arr2d # Verify by manual inspection
Out[14]:
array([[ 0., 1., 0., 1., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 1., 1., 0., 0., 1., 0.],
[ 0., 0., 0., 0., 0., 1., 0., 1., 0., 1.],
[ 0., 1., 1., 0., 0., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0., 0., 1., 0., 0.],
[ 1., 0., 0., 0., 0., 1., 0., 0., 1., 0.],
[ 0., 0., 0., 1., 0., 0., 0., 1., 0., 1.],
[ 1., 0., 0., 0., 0., 0., 1., 0., 1., 0.],
[ 1., 0., 0., 1., 0., 0., 0., 0., 1., 0.],
[ 0., 1., 0., 1., 0., 0., 0., 0., 0., 1.]])
In [15]: arr2d.sum(1) # Verify by counting ones in each row
Out[15]: array([ 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.])
注意:如果您正在尋找性能,我建議您使用np.argpartition
this other post
列出的基於np.argpartition
的方法。
使用此問題的答案來生成非重復的隨機數。 您可以使用random.sample
從Python的random
模塊,或np.random.choice
。
因此,只需對您的代碼進行少量修改:
>>> import numpy as np
>>> for row in arr2d:
... rand_cols = np.random.choice(range(10), 3, replace=False)
... # Or the python standard lib alternative (use `import random`)
... # rand_cols = random.sample(range(10), 3)
... row[rand_cols] = 1
...
>>> arr2d
array([[ 0., 0., 0., 0., 0., 1., 1., 1., 0., 0.],
[ 0., 0., 1., 0., 0., 0., 0., 0., 1., 1.],
[ 1., 0., 0., 0., 0., 0., 1., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 1., 0., 1., 1.],
[ 0., 0., 1., 1., 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 1., 1., 1., 0., 0., 0.],
[ 0., 1., 0., 0., 1., 1., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 1., 0., 0., 0., 1., 0.],
[ 0., 0., 1., 1., 0., 0., 0., 0., 1., 0.]])
我不認為您真的可以利用此處的列切片將值設置為1,除非您是從頭開始生成隨機數組。 這是因為您的列索引對於每一行都是隨機的 。 您最好將其以循環的形式保留,以提高可讀性。
我不確定這在性能方面有多好,但是相當簡潔。
arr2d[:, :3] = 1
map(np.random.shuffle, arr2d)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.