public static SignalNoiseRatio[] fit(DataFrame data, String clazz) {
        BaseVector<?, ?, ?> y = data.column(clazz);
        ClassLabels codec = ClassLabels.fit(y);

        if (codec.k != 2) {
            throw new UnsupportedOperationException("Signal Noise Ratio is applicable only to binary classification");
        }

        int n = data.nrow();
        int n1 = 0;
        for (int yi : codec.y) {
            if (yi == 0) {
                n1++;
            }
        }

        int n2 = n - n1;
        double[] x1 = new double[n1];
        double[] x2 = new double[n2];

        StructType schema = data.schema();

        return IntStream.range(0, schema.length()).mapToObj(i -> {
            StructField field = schema.field(i);
            if (field.isNumeric()) {
                Arrays.fill(x1, 0.0);
                Arrays.fill(x2, 0.0);
                BaseVector<?, ?, ?> xi = data.column(i);

                for (int l = 0, j = 0, k = 0; l < n; l++) {
                    if (codec.y[l] == 0) {
                        x1[j++] = xi.getDouble(l);
                    } else {
                        x2[k++] = xi.getDouble(l);
                    }
                }

                double mu1 = MathEx.mean(x1);
                double mu2 = MathEx.mean(x2);
                double sd1 = MathEx.sd(x1);
                double sd2 = MathEx.sd(x2);

                double s2n = Math.abs(mu1 - mu2) / (sd1 + sd2);
                return new SignalNoiseRatio(field.name, s2n);
            } else {
                return null;
            }
        }).filter(s2n -> s2n != null && !s2n.feature.equals(clazz)).toArray(SignalNoiseRatio[]::new);
    }
@Test
    public void testDefault() {
        System.out.println("Default");

        SignalNoiseRatio[] s2n = SignalNoiseRatio.fit(Default.data, "default");
        assertEquals(2, s2n.length);
        assertEquals(1.1832, s2n[0].s2n, 1E-4);
        assertEquals(0.0545, s2n[1].s2n, 1E-4);
    }