从距离矩阵中提取唯一值的Numpy算法

2024-09-30 00:32:31 发布

您现在位置:Python中文网/ 问答频道 /正文

输入数据:

我有以下distance_matrix

  [[1.        , 0.14285714, 0.25      , 0.83333333, 0.63636364],
   [0.14285714, 1.        , 0.33333333, 0.84615385, 0.66666667],
   [0.25      , 0.33333333, 1.        , 0.76923077, 0.58333333],
   [0.83333333, 0.84615385, 0.76923077, 1.        , 0.69230769],
   [0.63636364, 0.66666667, 0.58333333, 0.69230769, 1.        ]]

当前结果:

np.where(distane_matrix <= 0.25)返回以下输出:

(array([0, 0, 1, 2]), array([1, 2, 0, 0]))

预期结果:

(array([0, 0]), array([1, 2]))

说明:

用语言来表达,因为我知道:

  1. [0,1][1,0]具有相同的值
  2. [0,2][2,0]具有相同的值
  3. [0,1][0,2]满足np.where()的要求

我不想在输出中返回[1,0][2,0],因为这是冗余信息。最好的方法是什么?你知道吗


Tags: 数据方法语言信息npwherearraymatrix
3条回答

假设d是指定的距离矩阵。你知道吗

演示:

In [28]: r = np.triu(d, 1)

In [29]: r
Out[29]:
array([[0.        , 0.14285714, 0.25      , 0.83333333, 0.63636364],
       [0.        , 0.        , 0.33333333, 0.84615385, 0.66666667],
       [0.        , 0.        , 0.        , 0.76923077, 0.58333333],
       [0.        , 0.        , 0.        , 0.        , 0.69230769],
       [0.        , 0.        , 0.        , 0.        , 0.        ]])

In [30]: np.where((r>0) & (r<=0.25))
Out[30]: (array([0, 0], dtype=int64), array([1, 2], dtype=int64))

这里有一个masking的方法-

def get_lower_indices(a, thresh=0.25):
    n = a.shape[0]    
    ra = np.arange(n)
    mask = ra[:,None] < ra
    v = np.flatnonzero(a[mask] <= thresh)
    idx = np.concatenate(( [0], np.arange(n-1,0,-1).cumsum() ))
    c = np.searchsorted(idx, v,'right')-1
    r = v-idx[c]+c+1    
    return c,r

样本运行-

In [116]: a
Out[116]: 
array([[1.        , 0.14285714, 0.25      , 0.83333333, 0.63636364],
       [0.14285714, 1.        , 0.33333333, 0.84615385, 0.66666667],
       [0.25      , 0.33333333, 1.        , 0.76923077, 0.58333333],
       [0.83333333, 0.84615385, 0.76923077, 1.        , 0.69230769],
       [0.63636364, 0.66666667, 0.58333333, 0.69230769, 1.        ]])

In [117]: get_lower_indices(a, thresh=0.25)
Out[117]: (array([0, 0]), array([1, 2]))

如果你同意将上三角元素编辑成更高的值,这在阈值操作中不会被捕获,我们可以沿着这些线做一些事情-

def get_lower_indices_mask_editing(a, thresh=0.25):
    n = a.shape[0]
    r = np.arange(n)
    a[r[:,None] >= r] = 1
    return np.where(a<=thresh)

其他方法:

# @MaxU's soln
def triu_where(d):
    r = np.triu(d, 1)
    return np.where((r>0) & (r<=0.25))

计时-

In [231]: # Setup random array with larger size and no zeros
     ...: np.random.seed(0)
     ...: N = 5000
     ...: data = np.random.rand(N,N)
     ...: data = data.dot(data.T)
     ...: data = (data - data.min())/(data.max() -data.min())
     ...: data[data==0] = 0.1
     ...: np.fill_diagonal(data,1)

# @MaxU's soln
In [232]: %timeit triu_where(data)
10 loops, best of 3: 174 ms per loop

In [233]: %timeit get_lower_indices(data, thresh=0.25)
1 loop, best of 3: 318 ms per loop

In [234]: %timeit get_lower_indices_mask_editing(data, thresh=0.25)
10 loops, best of 3: 150 ms per loop

如果需要独立于选择条件的解决方案,可以考虑使用屏蔽数组:

import numpy.ma as ma

mat_masked = ma.array(your_mat, mask = np.triu(np.ones(np.shape(your_mat))))

从这里你会像以前一样继续

np.where(mat_masked <= 0.25) 

这还有一个好处,就是您的数据不受影响。你知道吗

相关问题 更多 >

    热门问题