12

私は、apache common math 3.0を使用して、特定のデータセットのビンを生成する方法を探していました(下限、上限、および必要なビンの数を指定することにより)。Frequency http://commons.apache.org/math/apidocs/org/apache/commons/math3/stat/Frequency.htmlを見てきました が、必要なものが得られません。間隔内の値の頻度(例:0から5までの値の数)。何か提案やアイデアはありますか?

4

5 に答える 5

17

Apache CommonsMath3を使用してヒストグラムを実装する簡単な方法は次のとおりです。

final int BIN_COUNT = 20;
double[] data = {1.2, 0.2, 0.333, 1.4, 1.5, 1.2, 1.3, 10.4, 1, 2.0}; 

long[] histogram = new long[BIN_COUNT];
org.apache.commons.math3.random.EmpiricalDistribution distribution = new org.apache.commons.math3.random.EmpiricalDistribution(BIN_COUNT);
distribution.load(data);
int k = 0;
for(org.apache.commons.math3.stat.descriptive.SummaryStatistics stats: distribution.getBinStats())
{
    histogram[k++] = stats.getN();
}
于 2012-06-19T21:13:04.970 に答える
8

私の知る限り、ApacheCommonsには適切なヒストグラムクラスはありません。私は自分で書くことになった。最小から最大まで線形に分散されたビンだけが必要な場合は、非常に簡単に記述できます。

多分このようなもの:

public static int[] calcHistogram(double[] data, double min, double max, int numBins) {
  final int[] result = new int[numBins];
  final double binSize = (max - min)/numBins;

  for (double d : data) {
    int bin = (int) ((d - min) / binSize);
    if (bin < 0) { /* this data is smaller than min */ }
    else if (bin >= numBins) { /* this data point is bigger than max */ }
    else {
      result[bin] += 1;
    }
  }
  return result;
}

編集:これが例です。

double[] data = { 2, 4, 6, 7, 8, 9 };
int[] histogram = calcHistogram(data, 0, 10, 4);
// This is a histogram with 4 bins, 0-2.5, 2.5-5, 5-7.5, 7.5-10.
assert histogram[0] == 1; // one point (2) in range 0-2.5
assert histogram[1] == 1; // one point (4) in range 2.5-5.
// etc..
于 2012-05-28T14:57:59.350 に答える
1

コードにバグがあると思います。以下の修正されたコードを参照してください。

public static int[] calcHistogram(double[] data, double min, double max, int numBins) {
  final int[] result = new int[numBins];
  final double binSize = (max - min)/numBins;

  for (double d : data) {
    int bin = (int) ((d - min) / binSize); // changed this from numBins
    if (bin < 0) { /* this data is smaller than min */ }
    else if (bin >= numBins) { /* this data point is bigger than max */ }
    else {
      result[bin] += 1;
    }
  }
  return result;
}
于 2012-09-18T02:24:52.163 に答える
0

これは@Altair7852の答えに追加されます。

y値のx値を生成する場合bin interval (各bin..akaの頻度histogram[] at index i)は完全な方法です。

    private fun displayHistogram(binCount: Int, data: DoubleArray) {
        val histogram = DoubleArray(binCount)
        val distribution = org.apache.commons.math3.random.EmpiricalDistribution(binCount)
        distribution.load(data)

        var k = 0
        for (stats in distribution.binStats) {
            histogram[k++] = stats.n.toDouble()
        }

        val binSize = (data.max()!!.toDouble() - data.min()!!.toDouble()) / binCount

        for (i in 0 until histogram.size) {
            series2?.appendData(DataPoint(generateHistogramXValues(data.min()!!.toDouble(), histogram.size, binSize)[i], histogram[i]), false, histogram.count())
        }
    }

これがx値の生成方法です

        val xValuesArray = DoubleArray(numberOfBIns)
        for (i in 0 until numberOfBIns) {
            if (i == 0){
                xValuesArray[i] = min
            }else{
                val previous = xValuesArray[i-1]
                xValuesArray[i] = previous+binSize
            }
        }
        return xValuesArray
    }

私はこれをAndroidでGraphViewグラフライブラリを使用して行っていますが、これはどのライブラリでも使用できます。

于 2019-06-09T06:39:37.880 に答える
0

これは、同じ関数のJavaストリームベースの実装です。

いくつかの便利な範囲、フィルター、およびカウント関数を使用します。

public static Long[] calcHistogram(Double[] data, Double min, Double max, Integer numBins) {
  final var interval = (max - min) / numBins;

  return IntStream.range(0, numBins)
      .boxed()
      .map(n -> {
        var binStart = min + n * interval;
        var binEnd = min + (n + 1) * interval;
        return Arrays.stream(data).filter(d -> d >= binStart && d < binEnd).count();
      })
      .toArray(Long[]::new);
}
于 2021-06-15T02:19:42.703 に答える