m Smallest values from upper triangular matrix with their indices as a list of tuples m Smallest values from upper triangular matrix with their indices as a list of tuples pandas pandas

m Smallest values from upper triangular matrix with their indices as a list of tuples


For an Inf filled array -

r,c = np.unravel_index(a.ravel().argsort()[:4], a.shape)out = zip(r,c,a[r,c])

For performance, consider using np.argpartition. So, replace a.ravel().argsort()[:4] with np.argpartition(a.ravel(), range(4))[:4].

Sample run -

In [285]: aOut[285]: array([[ inf,   1.,   3.,   2.,   1.],       [ inf,  inf,   2.,   3.,   2.],       [ inf,  inf,  inf,   5.,   4.],       [ inf,  inf,  inf,  inf,   1.],       [ inf,  inf,  inf,  inf,  inf]])In [286]: outOut[286]: [(0, 1, 1.0), (0, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0)]

For a generic case -

R,C = np.triu_indices(a.shape[1],1)idx = a[R,C].argsort()[:4]r,c = R[idx], C[idx]out = zip(r,c,a[r,c])

Sample run -

In [351]: aOut[351]: array([[ 68.,  67.,  81.,  23.,  16.],       [ 84.,  83.,  20.,  66.,  48.],       [ 58.,  72.,  98.,  63.,  30.],       [ 61.,  40.,   1.,  86.,  22.],       [ 29.,  95.,  38.,  22.,  95.]])In [352]: outOut[352]: [(0, 4, 16.0), (1, 2, 20.0), (3, 4, 22.0), (0, 3, 23.0)]

For performance, consider using np.argpartition. So, replace a[R,C].argsort()[:4] with np.argpartition(a[R,C], range(4))[:4].


Something like this works:

import numpy as npa = np.random.rand(4,4)tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row)]sorted(tuples,key=lambda x: x[2])[:10]

Where k=10 ([:10]) from your question.

If you only want the upper triangular elements you can add a condition to the list comprehension:

a = np.random.rand(4,4)tuples = [(ix,iy, a[ix,iy]) for ix, row in enumerate(a) for iy, i in enumerate(row) if ix<=iy]sorted(tuples,key=lambda x: x[2])


If my np.array() is n I could get the n smallest values from it by flattening it (with *np.ndenumerate()), and using the heapq module's .heapify() and .smallest() methods like so:

#!pythonflattened = [(y,x) for x,y in np.ndenumerate(n)]# tuples reversed for natural sorting on values rather than co-ordsheapq.heapify(flattened)results = heapq.nsmallest(4, flattened)

But this will use plenty of extra memory and will extract the data and co-ordinates out of Numpy's efficient arrays into Python's native lists. So there's probably much better ways to do it more natively in Python.