我在一個陣列中有未定義形狀的單熱編碼資料ndim = 3,例如:
import numpy as np
arr = np.array([ # Axis 0
[ # Axis 1
[0, 1, 0], # Axis 2
[1, 0, 0],
],
[
[0, 0, 1],
[0, 1, 0],
],
])
我想要的是將已知部分子陣列的值混洗axis=2。
如果這個分數是0.25,那么結果可能是:
arr = np.array([
[
[1, 0, 0], # Shuffling happened here
[1, 0, 0],
],
[
[0, 0, 1],
[0, 1, 0],
],
])
我知道如何使用迭代方法來做到這一點,例如:
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
if np.random.choice([0, 1, 2, 3]) == 0:
np.random.shuffle(arr[i][j])
但這是極其低效的。
編輯:正如評論中所建議的,已知分數的隨機選擇應遵循統一的規律。
uj5u.com熱心網友回復:
一種方法:
import numpy as np
np.random.seed(42)
fraction = 0.25
total = arr.shape[0] * arr.shape[1]
# pick arrays to be shuffled
indices = np.random.choice(np.arange(total), size=int(total * fraction), replace=False)
# convert the each index to the corresponding multi-index
multi_indices = np.unravel_index(indices, arr.shape[:2])
# create view using multi_indices
selected = arr[multi_indices]
# shuffle select by applying argsort on random values of the same shape
shuffled = np.take_along_axis(selected, np.argsort(np.random.random(selected.shape), axis=1), axis=1)
# set the array to the new values
arr[multi_indices] = shuffled
print(arr)
輸出 (單次運行)
[[[0 1 0]
[0 0 1]]
[[0 0 1]
[0 1 0]]]
uj5u.com熱心網友回復:
您的迭代方法很棒,并且在涉及的邏輯運算元量方面絕對是最佳解決方案。據我所知,唯一做得更好的方法是利用 numpy 的矢量化加速。下面的代碼是一個例子
def permute_last_maybe(x):
N, M, K = x.shape
y = np.transpose(x, [2, 0, 1])
y = np.random.permutation(y)
y = np.transpose(y, [1, 2, 0])
mask = (np.random.random((N, M, 1)) > 0.25) * np.ones([N, M, K])
return np.where(mask, x, y)
timeit 魔術顯示 300 us 而不是 4.2 ms 與 size 陣列(40, 40, 30)。請注意,此代碼不使用來自 numpy的新隨機生成器(我嘗試過,但創建類實體的多載很重要)。
我可能還應該提到這個函式不會改變給定的陣列 x 而是回傳它的一個副本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/335464.html
