使用 numpy 操作从每行填充的 numpy 数组和非填充值的数量中选择随机数的最快方法

我有一个 2D numpy 数组,每一行都填充了(下面的示例使用 -1)。


对于每一行,我想选择一个随机数,不包括填充,并仅使用 numpy 操作获取每一行的非填充值的数量。


这是一个最小的例子。我为 pad 选择了 -1,但 pad 可以是任何负整数。


import numpy as np

numList = [[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)

numArray


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]])

对于长度,输出应该看起来像这样


LengthsResults

[5, 4, 6, 2, 4]. 

这是一个示例输出,用于为每一行选择一个随机的非填充数字。


randomNonPad

[84, 45, 0, 0, 34]

编辑:


我在看 np.where,它可以让你根据条件和 numpy 随机选择过滤掉你的 numpy 数组的一部分,它可以让你为数组选择一个随机数。虽然我不确定如何处理 np.where,但似乎您可以将其更改为某些东西,但我不确定是什么,或者即使它是正确的方法。对于 python,您可以从一个列表开始,并将其附加到任意长度,但对于 numpy,您需要提前建立数组长度。


莫回无
浏览 113回答 2
2回答

烙印99

行中负数的索引,也是非填充元素的长度,最简单的方法是lengths&nbsp;=&nbsp;np.argmin(numArray,&nbsp;axis=1)这假定行内所有元素的填充数相同。对于没有负数的行,这将无法正常工作,因此您可以使用以下方法修复它:lengths[np.take_along_axis(numArray,&nbsp;lengths.reshape(-1,&nbsp;1),&nbsp;axis=1).ravel()&nbsp;>=&nbsp;0]&nbsp;=&nbsp;numArray.shape[1]您现在可以使用此信息在您的行中生成一个随机索引数组:indices&nbsp;=&nbsp;np.random.randint(lengths)并应用索引获取相应的元素:result&nbsp;=&nbsp;np.take_along_axis(numArray,&nbsp;indices.reshape(-1,&nbsp;1),&nbsp;axis=1)虽然清理lengths数组可能是更快的选择,但更短的表达式可能类似于lengths&nbsp;=&nbsp;np.where(np.any(numArray&nbsp;<&nbsp;0,&nbsp;axis=1),&nbsp;np.argmin(numArray,&nbsp;axis=1),&nbsp;numArray.shape[1])此外,如果您的填充数不是一致的负数,您将需要替换np.argmin(numArray, axis=1)为np.argmax(numArray < 0, axis=1), 或np.argmin(numArray >= 0, axis=1),无论您使用哪种方法计算lengths。

慕田峪9158850

注意——这可能与@Mad 的回答重叠;我会留下它,以防备选解释消除一些混乱。In [32]: numList = [[0, 32, 84, 93, 1023, -1], [0, 23, 33, 45, -1, -1], [0, 10, 15, 21, 2&nbsp; &nbsp; ...: 4, 25], [0, 23, -1, -1, -1, -1], [0 , 13, 33, 34, -1, -1]]&nbsp;&nbsp; &nbsp; ...: numArray = np.array(numList)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;In [33]: numArray&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[33]:&nbsp;array([[&nbsp; &nbsp;0,&nbsp; &nbsp;32,&nbsp; &nbsp;84,&nbsp; &nbsp;93, 1023,&nbsp; &nbsp;-1],&nbsp; &nbsp; &nbsp; &nbsp;[&nbsp; &nbsp;0,&nbsp; &nbsp;23,&nbsp; &nbsp;33,&nbsp; &nbsp;45,&nbsp; &nbsp;-1,&nbsp; &nbsp;-1],&nbsp; &nbsp; &nbsp; &nbsp;[&nbsp; &nbsp;0,&nbsp; &nbsp;10,&nbsp; &nbsp;15,&nbsp; &nbsp;21,&nbsp; &nbsp;24,&nbsp; &nbsp;25],&nbsp; &nbsp; &nbsp; &nbsp;[&nbsp; &nbsp;0,&nbsp; &nbsp;23,&nbsp; &nbsp;-1,&nbsp; &nbsp;-1,&nbsp; &nbsp;-1,&nbsp; &nbsp;-1],&nbsp; &nbsp; &nbsp; &nbsp;[&nbsp; &nbsp;0,&nbsp; &nbsp;13,&nbsp; &nbsp;33,&nbsp; &nbsp;34,&nbsp; &nbsp;-1,&nbsp; &nbsp;-1]])每行焊盘数:In [34]: np.sum(numArray==-1, axis=1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[34]: array([1, 2, 0, 4, 2])每行非填充数:In [35]: np.sum(numArray!=-1, axis=1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[35]: array([5, 4, 6, 2, 4])我不知道假设填充值都在最后是否会使它更有效率。样本有点小,无法把握好时机。从每一行中随机选择一个非填充,显而易见的第一次尝试是行列表理解:In [40]: [np.random.choice(row[row!=-1]) for row in numArray]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[40]: [32, 0, 0, 23, 34]或者从长度(上面)开始工作(并假设尾部填充)我们可以为每一行选择一个随机索引:In [46]: [np.random.choice(i) for i in Out[35]]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[46]: [1, 2, 1, 0, 1]In [47]: numArray[np.arange(numArray.shape[0]), [np.random.choice(i) for i in Out[35]]]&nbsp;&nbsp;Out[47]: array([93, 45, 21, 23, 13])在@Mad 的帽子提示中,randint接受范围值的列表/数组,choice理解可以替换为:In [49]: np.random.randint(Out[35])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[49]: array([3, 1, 2, 1, 1])In [50]: numArray[np.arange(numArray.shape[0]), np.random.randint(Out[35])]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;Out[50]: array([ 0, 23, 24,&nbsp; 0,&nbsp; 0])
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python