在成对比较 NxN numpy 数组中找到 N 个最小值?

问题描述

我有一个双精度值的python NxN numpy成对数组(矩阵)。例如,(i,j) 的每个数组元素都是 ij 项之间的度量。对角线,其中 i==j,是 1,因为它是对自身的成对测量。这也意味着 2D NxN numpy 数组可以表示为矩阵三角形形式(numpy 数组的一半与对角线上的另一半相同)。

截断的表示:

[[1.         0.11428571 0.04615385 ... 0.13888889 0.07954545 0.05494505]
 [0.11428571 1.         0.09836066 ... 0.06578947 0.09302326 0.07954545]
 [0.04615385 0.09836066 1.         ... 0.07843137 0.09821429 0.11711712]
 ...
 [0.13888889 0.06578947 0.07843137 ... 1.         0.34313725 0.31428571]
 [0.07954545 0.09302326 0.09821429 ... 0.34313725 1.         0.64130435]
 [0.05494505 0.07954545 0.11711712 ... 0.31428571 0.64130435 1.        ]]

我想得到最小的 N 个值,同时不包括两次成对值,因为成对重复就是这种情况,例如 (5,6) == (6,5),并且我不想包含任何与 1 相同的对角线值,其中 i == j

我知道 numpy 有 partition 方法,我已经看到了很多平面数组的例子,但我很难找到任何简单的成对比较矩阵。 >

编辑 #1 根据我在下面的第一个回复,我实施了:

seventyPercentInt: int = round((populationSizeInt/100)*70)

upperTriangleArray = dataArray[np.triu_indices(len(dataArray),1)]
seventyPercentArray = upperTriangleArray[np.argpartition(upperTriangleArray,seventyPercentInt)][0:seventyPercentInt]

print(len(np.unique(seventyPercentArray)))

upperTriangleArray numpy 数组有 1133265 个元素可以从中选择最低的 k在这种情况下,kseventyPercentInt 表示,大约为 1054 个值。但是,当我应用 np.argpartition 时,只返回 0 的值。

平面阵列upperTriangleArray被缩减为一个形状(1133265,)。

解决方

根据下面的第一个回复(接受的答案),我的代码有效:

upperTriangleArray = dataArray[np.triu_indices(len(dataArray),1)]

seventyPercentInt: int = round((len(upperTriangleArray)/100)*70)

seventyPercentArray = upperTriangleArray[np.argpartition(upperTriangleArray,seventyPercentInt)][0:seventyPercentInt]

我在使用 seventyPercentInt 时遇到了一些小麻烦(我自己造成的)。我没有选取 70% 的成对元素,而是选取了 70% 的元素进行比较。两个截然不同的价值观。

解决方法

您可以使用 np.triu_indices 仅保留上三角形的值。

然后您可以使用 np.argpartition,如下例所示。

import numpy as np

A = np.array([[1.0,0.1,0.2,0.3],[0.1,1.0,0.4,0.5],[0.2,0.3,0.6],[0.3,0.5,1.0]])

A_upper_triangle = A[np.triu_indices(len(A),1)]

print(A_upper_triangle)
# return [0.1 0.2 0.3 0.3 0.5 0.4]

k=2

print(A_upper_triangle[np.argpartition(A_upper_triangle,k)][0:k])
#return [0.1 0.2]