问题:给定一个索引元组,以上三角索引返回其顺序。这是一个示例:
假设我们有一个形状为(3,3)的方阵A。
A有6个上三角索引,分别是(0,0),(0,1),(0,2),(1,1),(1、2),(2,2)。
现在我知道索引(1、2)处的元素,该元素属于A的上三角部分。我想返回4(这意味着它是所有上三角索引中的第5个元素。)
一般来说,有什么想法吗?
最好, 志浩
答案 0 :(得分:5)
可以写下明确的公式:
def utr_idx(N, i, j):
return (2*N+1-i)*i//2 + j-i
演示:
>>> N = 127
>>> X = np.transpose(np.triu_indices(N))
>>> utr_idx(N, *X[2123])
2123
答案 1 :(得分:4)
对于 n×n 矩阵,上三角形的(i,j)项是 i×(2×n-i矩阵的第+1)/ 2 + ji 个元素。
我们也可以反算,并通过以下方法获得第 k 个元素的(i,j)元素:
i =⌊(-√((2n + 1) 2 -8k)+ 2n + 1)/2⌋和 j = k + ii ×(2×n-i + 1)/ 2
例如:
from math import floor, sqrt
def coor_to_idx(n, i, j):
return i*(2*n-i+1)//2+j-i
def idx_to_coor(n, k):
i = floor((-sqrt((2*n+1)*(2*n+1)-8*k)+2*n+1)/2)
j = k + i - i*(2*n-i+1)//2
return i, j
例如:
>>> [idx_to_coor(4, i) for i in range(10)]
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
>>> [coor_to_idx(4, i, j) for i in range(4) for j in range(i, 4)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
鉴于数字不是很大(如果数字很大,那么计算不再是在恒定时间内完成的),因此我们可以在 O(1)中计算第 k 个坐标,例如:
>>> idx_to_coor(1234567, 123456789)
(100, 5139)
等效于通过枚举获取它:
>>> next(islice(((i, j) for i in range(1234567) for j in range(i, 1234567)), 123456789, None))
(100, 5139)
将索引转换为坐标时,由于浮点数的不精确性,对于大量对象,还可能会有一些舍入误差。
答案 2 :(得分:2)
IIUC,您可以使用itertools
组合with replacement
>>> ind = tuple(itertools.combinations_with_replacement(range(3),2))
((0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2))
要检索索引,只需使用index
方法
>>> ind.index((1,2))
4
答案 3 :(得分:2)
您可以使用np.triu_indices和dictionary:
import numpy as np
iu1 = np.triu_indices(3)
table = {(i, j): c for c, (i, j) in enumerate(zip(*iu1))}
print(table[(1, 2)])
输出
4
答案 4 :(得分:1)
类似于@DanielMesejo,您可以将np.triu_indices
与argwhere
或nonzero
一起使用:
my_index = (1,2)
>>> np.nonzero((np.stack(np.triu_indices(3), axis=1) == my_index).all(1))
(array([4]),)
>>> np.argwhere((np.stack(np.triu_indices(3), axis=1) == my_index).all(1))
array([[4]])
说明:
np.stack(np.triu_indices(3), axis=1)
按顺序提供上三角的索引:
array([[0, 0],
[0, 1],
[0, 2],
[1, 1],
[1, 2],
[2, 2]])
因此,您要做的就是找到与[1,2]
匹配的位置(您可以使用==
运算符和all
进行匹配)
答案 5 :(得分:1)
构造较高的索引会很昂贵。我们可以像这样直接获取相应的索引-
def triu_index(N, x, y):
# Get index corresponding to (x,y) in upper triangular list
idx = np.r_[0,np.arange(N,1,-1).cumsum()]
return idx[x]+y-x
样品运行-
In [271]: triu_index(N=3, x=1, y=2)
Out[271]: 4