Sort matrix, but return the indices that would sort it, not the data itself (NumPy argsort) #3466
Replies: 4 comments
-
|
Here is an ugly implementation of this. function argsort<T = unknown>(
input: T[],
compare?: (a: T, b: T) => number,
): number[] {
// From https://stackoverflow.com/a/65410414
return input
.map((value, index) => [value, index])
.sort(
compare !== undefined
? (a, b) => compare(a[0] as T, b[0] as T)
: undefined,
)
.map((arr) => arr[1] as number);
} |
Beta Was this translation helpful? Give feedback.
-
|
I don't think you missed it; I do not think mathjs has a method equivalent to argsort. If so, it would presumably be in the "matrix" section of functions, where |
Beta Was this translation helpful? Give feedback.
-
|
Adding a function like const A = [3, 1, 2]
const i = [1, 2, 0] // this will be returned by this new function argsort
const ASorted = math.subset(A, math.index(i))Thoughts:
Anyone interested in thinking through the API for this function and implementing it in a PR? Help would be very welcome. |
Beta Was this translation helpful? Give feedback.
-
|
Also, in the example above, unravel_indices might kind of go together with argsort. Those 2 functions were the only operations missing for me to implement my algorithm described above. I'm not entirely sure where the "bounds" of what makes sense in math.js are though, but it is just another idea. Here's the simple TypeScript I threw together to make it work as well. There's probably a much better way to do the types, but I've never used Math.js before and was just learning what types are available and all that. export function unravel_index<T extends math.MathArray>(
x: T,
sizes: number[],
): math.Matrix<math.MathNumericType> {
let work: T = x.slice() as T;
const result: T[] = [];
for (let dim = sizes.length - 1; dim >= 0; dim--) {
result[dim] = math.mod(work, sizes[dim] as number) as T;
work = math.floor(math.divide(work, sizes[dim] as number) as T) as T;
}
return math.matrix(result);
}On the other hand, this is a very slippery slope! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
I was looking around at the documentation, but I don't think there's a comparable method in math.js to NumPy's argsort. Unless I've missed it, I think it'd be a handy feature to have!
Examples from NumPy:
As an example, I am using argsort to make pairs between the most similar elements of 2 arrays.
I create a 2D matrix, with one dimension representing the index of 1 array, and the other represents the 2nd array. This is filled with numbers that represent the similarity of any 2 given elements of the arrays. Then I flatten the matrix, argsort it, unravel_index to get the original matrix indices back, and do a little more processing.
The end result is a single array, containing tuples (technically arrays) of the x,y coordinates of the original matrix, sorted by similarity. Then I can go through and fetch the pairs I want.
In hindsight, perhaps there was a better, already implemented way to solve this in JS, but I had the Python NumPy code so my first thought was to just directly port it over...
Beta Was this translation helpful? Give feedback.
All reactions