亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 numpy 操作從每行填充的 numpy 數組和非填充值的數量中選擇隨機數的最快方法

使用 numpy 操作從每行填充的 numpy 數組和非填充值的數量中選擇隨機數的最快方法

莫回無 2022-12-06 15:05:49
我有一個 2D numpy 數組,每一行都填充了(下面的示例使用 -1)。對于每一行,我想選擇一個隨機數,不包括填充,并僅使用 numpy 操作獲取每一行的非填充值的數量。這是一個最小的例子。我為 pad 選擇了 -1,但 pad 可以是任何負整數。import numpy as npnumList = [[0, 32, 84, 93, 1023, -1], [0, 23, 33, 45, -1, -1], [0, 10, 15, 21, 24, 25], [0, 23, -1, -1, -1, -1], [0 , 13, 33, 34, -1, -1]]numArray = np.array(numList)numArrayarray([[   0,   32,   84,   93, 1023,   -1],       [   0,   23,   33,   45,   -1,   -1],       [   0,   10,   15,   21,   24,   25],       [   0,   23,   -1,   -1,   -1,   -1],       [   0,   13,   33,   34,   -1,   -1]])對于長度,輸出應該看起來像這樣LengthsResults[5, 4, 6, 2, 4]. 這是一個示例輸出,用于為每一行選擇一個隨機的非填充數字。randomNonPad[84, 45, 0, 0, 34]編輯:我在看 np.where,它可以讓你根據條件和 numpy 隨機選擇過濾掉你的 numpy 數組的一部分,它可以讓你為數組選擇一個隨機數。雖然我不確定如何處理 np.where,但似乎您可以將其更改為某些東西,但我不確定是什么,或者即使它是正確的方法。對于 python,您可以從一個列表開始,并將其附加到任意長度,但對于 numpy,您需要提前建立數組長度。
查看完整描述

2 回答

?
烙印99

TA貢獻1829條經驗 獲得超13個贊

行中負數的索引,也是非填充元素的長度,最簡單的方法是

lengths = np.argmin(numArray, axis=1)

這假定行內所有元素的填充數相同。對于沒有負數的行,這將無法正常工作,因此您可以使用以下方法修復它:

lengths[np.take_along_axis(numArray, lengths.reshape(-1, 1), axis=1).ravel() >= 0] = numArray.shape[1]

您現在可以使用此信息在您的行中生成一個隨機索引數組:

indices = np.random.randint(lengths)

并應用索引獲取相應的元素:

result = np.take_along_axis(numArray, indices.reshape(-1, 1), axis=1)

雖然清理lengths數組可能是更快的選擇,但更短的表達式可能類似于

lengths = np.where(np.any(numArray < 0, axis=1), np.argmin(numArray, axis=1), numArray.shape[1])

此外,如果您的填充數不是一致的負數,您將需要替換np.argmin(numArray, axis=1)np.argmax(numArray < 0, axis=1), 或np.argmin(numArray >= 0, axis=1),無論您使用哪種方法計算lengths。


查看完整回答
反對 回復 2022-12-06
?
慕田峪9158850

TA貢獻1794條經驗 獲得超7個贊

注意——這可能與@Mad 的回答重疊;我會留下它,以防備選解釋消除一些混亂。


In [32]: numList = [[0, 32, 84, 93, 1023, -1], [0, 23, 33, 45, -1, -1], [0, 10, 15, 21, 2

    ...: 4, 25], [0, 23, -1, -1, -1, -1], [0 , 13, 33, 34, -1, -1]] 

    ...: numArray = np.array(numList)                                                    

In [33]: numArray                                                                        

Out[33]: 

array([[   0,   32,   84,   93, 1023,   -1],

       [   0,   23,   33,   45,   -1,   -1],

       [   0,   10,   15,   21,   24,   25],

       [   0,   23,   -1,   -1,   -1,   -1],

       [   0,   13,   33,   34,   -1,   -1]])

每行焊盤數:


In [34]: np.sum(numArray==-1, axis=1)                                                    

Out[34]: array([1, 2, 0, 4, 2])

每行非填充數:


In [35]: np.sum(numArray!=-1, axis=1)                                                    

Out[35]: array([5, 4, 6, 2, 4])

我不知道假設填充值都在最后是否會使它更有效率。樣本有點小,無法把握好時機。


從每一行中隨機選擇一個非填充,顯而易見的第一次嘗試是行列表理解:


In [40]: [np.random.choice(row[row!=-1]) for row in numArray]                            

Out[40]: [32, 0, 0, 23, 34]

或者從長度(上面)開始工作(并假設尾部填充)我們可以為每一行選擇一個隨機索引:


In [46]: [np.random.choice(i) for i in Out[35]]                                          

Out[46]: [1, 2, 1, 0, 1]

In [47]: numArray[np.arange(numArray.shape[0]), [np.random.choice(i) for i in Out[35]]]  

Out[47]: array([93, 45, 21, 23, 13])

在@Mad 的帽子提示中,randint接受范圍值的列表/數組,choice理解可以替換為:


In [49]: np.random.randint(Out[35])                                                      

Out[49]: array([3, 1, 2, 1, 1])

In [50]: numArray[np.arange(numArray.shape[0]), np.random.randint(Out[35])]              

Out[50]: array([ 0, 23, 24,  0,  0])


查看完整回答
反對 回復 2022-12-06
  • 2 回答
  • 0 關注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號