I'd like to use an argsort function on arrays or arraylist or an other data structure in Java but I didn't find in the documentation an argsort function. I know there is a sort method on the Collections class but there isn't any argsort method. Is there any class with an argsort method already implemented?
I've found this class, I hope it's what you wanted:
import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;
public final class ArrayUtils {
public static int[] argsort(final float[] a) {
return argsort(a, true);
}
public static int[] argsort(final float[] a, final boolean ascending) {
Integer[] indexes = new Integer[a.length];
for (int i = 0; i < indexes.length; i++) {
indexes[i] = i;
}
Arrays.sort(indexes, new Comparator<Integer>() {
@Override
public int compare(final Integer i1, final Integer i2) {
return (ascending ? 1 : -1) * Float.compare(a[i1], a[i2]);
}
});
return asArray(indexes);
}
public static <T extends Number> int[] asArray(final T... a) {
int[] b = new int[a.length];
for (int i = 0; i < b.length; i++) {
b[i] = a[i].intValue();
}
return b;
}
public static double[] castOf(final float[] x) {
double[] y = new double[x.length];
for (int i = 0; i < y.length; i++) {
y[i] = x[i];
}
return y;
}
public static int[] castOf(final long[] original) {
return castOf(original, original.length);
}
public static int[] castOf(final long[] original, final int newLength) {
int[] cast = new int[newLength];
int length = Math.min(cast.length, original.length);
for (int i = 0; i < length; i++) {
long o = original[i];
if (o < Integer.MIN_VALUE || o > Integer.MAX_VALUE) {
throw new IllegalArgumentException();
}
cast[i] = (int) o;
}
return cast;
}
public static float[][] copyOf(final float[][] x, final int newLength) {
float[][] y = new float[newLength][];
for (int i = 0; i < y.length; i++) {
if (x[i] != null) {
y[i] = Arrays.copyOf(x[i], x[i].length);
}
}
return y;
}
/**
* Assigns a random value to each element of the specified array of doubles.
*/
public static void fillRandom(final double[] x, final Random rng) {
for (int i = 0; i < x.length; i++) {
x[i] = rng.nextDouble();
}
}
private ArrayUtils() {
}
}
Link: Code
As of 2017, you can find an argsort function in the ND4J library (which is probably the closest Java equivalent to numpy). It didn't make it into the 0.9.1 release in 2017, but it looks as though it will be in the upcoming 0.9.2 release. The code is actually derived from the array4j code that JetStream copied into their answer. array4j seems to be abandoned now, so ND4J will probably be preferable as soon as argsort has made it into a release. Once 0.9.2 is released, you'll be able to install it from the Maven Central repository.
Incidentally, you mention in a comment on JetStream's answer that
I was wondering why there wasn't any class with this argsort method. It exists in Python numpy for instance...
That's not a fair comparison, since numpy isn't part of the Python standard libraries, any more than ND4J is for Java. Neither language includes argsort in the standard libraries, and both have it available in a third-party library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With