我有一个数组X:
X = np.array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
我希望在此数组中找到多个值的行的索引:
searched_values = np.array([[4, 2],
[3, 3],
[5, 6]])
对于此示例,我想要一个类似的结果:
[0,3,4]
我有一个执行此操作的代码,但我认为它过于复杂:
X = np.array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
searched_values = np.array([[4, 2],
[3, 3],
[5, 6]])
result = []
for s in searched_values:
idx = np.argwhere([np.all((X-s)==0, axis=1)])[0][1]
result.append(idx)
print(result)
我发现了this answer的类似问题,但它仅适用于一维数组。
有没有一种方法可以更简单地完成我想要的工作?
参考方案
方法1
一种方法是使用NumPy broadcasting
,就像这样-
np.where((X==searched_values[:,None]).all(-1))[1]
方法#2
一种内存有效的方法是将每一行转换为等效的线性索引,然后使用np.in1d
,如下所示-
dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
np.ravel_multi_index(searched_values.T,dims)))[0]
方法3
另一种使用np.searchsorted
且具有相同的转换为线性索引等效项的原理的内存有效方法将是这样的-
dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]
请注意,此np.searchsorted
方法假定searched_values
中X
的每一行都有匹配项。
np.ravel_multi_index
如何工作?
此函数为我们提供了线性索引当量数。它接受2D
的n-dimensional indices
数组,设置为列,并将这些索引要映射到其上的n维网格本身的形状以及要计算的等效线性索引。
让我们使用针对当前问题的输入。以输入X
为例,并注意它的第一行。由于我们试图将X
的每一行转换为其等效的线性索引,并且由于np.ravel_multi_index
假设每一列都是一个索引元组,因此我们需要先对X
进行转置,然后再馈入该函数。由于在这种情况下X
中每行的元素数是2
,因此要映射到的n维网格将是2D
。在X
中每行3个元素,它应该是3D
网格进行映射,依此类推。
要查看此函数如何计算线性索引,请考虑X
的第一行-
In [77]: X
Out[77]:
array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
我们将n维网格的形状设为dims
-
In [78]: dims
Out[78]: array([10, 7])
让我们创建一个二维网格,以查看该映射如何工作以及如何使用np.ravel_multi_index
计算线性索引-
In [79]: out = np.zeros(dims,dtype=int)
In [80]: out
Out[80]:
array([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]])
让我们从X
设置第一个索引元组,即从X
到网格的第一行-
In [81]: out[4,2] = 1
In [82]: out
Out[82]:
array([[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]])
现在,要查看刚设置的元素的线性索引等效项,让我们展平并使用np.where
来检测该1
。
In [83]: np.where(out.ravel())[0]
Out[83]: array([30])
如果考虑行优先排序,也可以计算得出。
让我们使用np.ravel_multi_index
并验证那些线性索引-
In [84]: np.ravel_multi_index(X.T,dims)
Out[84]: array([30, 66, 61, 24, 41])
因此,我们将具有对应于X
中每个索引元组的线性索引,即X
中的每一行。
为np.ravel_multi_index
选择尺寸以形成唯一的线性索引
现在,将X
的每一行视为n维网格的索引元组并将每个这样的元组转换为标量的背后的想法是要具有对应于唯一元组的唯一标量,即X
中的唯一行。
让我们再看一下X
-
In [77]: X
Out[77]:
array([[4, 2],
[9, 3],
[8, 5],
[3, 3],
[5, 6]])
现在,如前一节所述,我们将每一行都视为索引元组。在每个这样的索引元组中,第一个元素将代表n-dim网格的第一个轴,第二个元素将是网格的第二个轴,依此类推,直到X
中每行的最后一个元素。本质上,每一列将代表网格的一个维度或轴。如果要将所有来自X
的元素映射到相同的n-dim网格,则需要考虑这样建议的n-dim网格的每个轴的最大拉伸。假设我们在X
中处理正数,那么这样的延展将是X
+ 1中每一列的最大值。之所以说+ 1
是因为Python遵循0-based
索引。因此,例如X[1,0] == 9
将映射到建议网格的第十行。同样,X[4,1] == 6
将转到该网格的7th
列。
因此,对于我们的示例案例,我们有-
In [7]: dims = X.max(axis=0) + 1 # Or simply X.max(0) + 1
In [8]: dims
Out[8]: array([10, 7])
因此,对于我们的示例案例,我们将需要至少为(10,7)
形状的网格。沿尺寸的更多长度不会受到损害,并且也会为我们提供独特的线性指标。
结束语:这里要注意的一件事是,如果X
中有负数,则需要在X
中的每一列上添加适当的偏移量,以使这些索引元组成为正数,然后再使用np.ravel_multi_index
。
我有一个Python脚本在某些深度学习模型上运行推理。有什么办法可以找出GPU资源的利用率水平?例如,使用着色器,float16乘法器等。我似乎在网上找不到太多有关这些GPU资源的文档。谢谢! 参考方案 您可以尝试在像Renderdoc这样的GPU分析器中运行pyxthon应用程序。它将分析您的跑步情况。您将能够获得有关已使用资源,已用缓冲区,不同渲染状态上…
Python:图像处理可产生皱纹纸效果 - python也许很难描述我的问题。我正在寻找Python中的算法,以在带有某些文本的白色图像上创建皱纹纸效果。我的第一个尝试是在带有文字的图像上添加一些真实的皱纹纸图像(具有透明度)。看起来不错,但副作用是文本没有真正起皱。所以我正在寻找更好的解决方案,有什么想法吗?谢谢 参考方案 除了使用透明性之外,假设您有两张相同尺寸的图像,一张在皱纹纸上明亮,一张在白色背景上有深…
Python uuid4,如何限制唯一字符的长度 - python在Python中,我正在使用uuid4()方法创建唯一的字符集。但是我找不到将其限制为10或8个字符的方法。有什么办法吗?uuid4()ffc69c1b-9d87-4c19-8dac-c09ca857e3fc谢谢。 参考方案 尝试:x = uuid4() str(x)[:8] 输出:"ffc69c1b" Is there a way to…
Python sqlite3数据库已锁定 - python我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…
python:ConfigParser对象,然后再阅读一次 - python场景:我有一个配置文件,其中包含要执行的自动化测试的列表。这些测试是长期循环执行的。 配置文件的设计方式使ConfigParser可以读取它。由于有两个三个参数,因此我需要通过每个测试。现在,此配置文件由script(s1)调用,并且按照配置文件中的列表执行测试。Script(s1)第一次读取配置,并且在每次测试完成后都会执行。阅读两次的要求:由于可能会…