2

Excellでデータ分析アドインのヒストグラム機能を複製する関数を作成しています。基本的に、サンプルデータの入力が提供され、次にビンの範囲も提供されます。ビンの範囲は単調に増加する必要があり、私の場合は具体的に[0 20 406080100]である必要があります。Excellは、サンプルが下限(左端)より大きく、上限(右端)以下である場合に、サンプルがビン範囲に該当するかどうかを計算します。

以下にビンソートアルゴリズムを記述しました。これにより、data0(非常に近い)に対して不適切な出力が得られますが、data1およびdata2に対しては適切な出力が得られます。この場合の適切な意味は、このアルゴリズムからの出力が、サンプル数がビンの隣で集計されるExcellが生成するテーブルの出力と正確に一致することを意味します。どんな助けでも大歓迎です!

#include <iostream>

int main(int argc, char **agv)
{
    const int SAMPLE_COUNT      = 21;
    const int BIN_COUNT         = 6;
    int binranges[BIN_COUNT]    = {0, 20, 40, 60, 80, 100};
    int bins[BIN_COUNT]         = {0, 0, 0, 0, 0, 0};

    int data0[SAMPLE_COUNT] =  {4,82,49,17,89,73,93,86,74,36,74,55,81,61,88,94,72,65,35,25,79};
    // for data0 excell's bins read:
    // 0    0
    // 20   2
    // 40   3
    // 60   2
    // 80   7
    // 100  7
    //
    // instead output of bins is: 203277

    int data1[SAMPLE_COUNT] = {88,83,0,0,95,86,0,94,92,77,94,73,93,90,50,95,93,83,0,95,91};
    //for data1 excell and this algorithm both yield:
    // 0    4
    // 20   0
    // 40   0
    // 60   1
    // 80   2
    // 100  14  (correct)

    int data2[SAMPLE_COUNT] = {58,48,75,68,85,78,74,83,83,75,67,58,75,58,84,68,57,88,55,79,72};
    //for data2 excell and this algorithm both yield:
    // 0    0
    // 20   0
    // 40   0
    // 60   6
    // 80   10
    // 100  5   (correct)

    for (unsigned int binNum = 1; binNum < BIN_COUNT; ++binNum)
    {
        const int leftEdge = binranges[binNum - 1];
        const int rightEdge = binranges[binNum];

        for (unsigned int sampleNum = 0; sampleNum < SAMPLE_COUNT; ++sampleNum)
        {
            const int sample = data0[sampleNum];

            if (binNum == 1)
            {
                if (sample >= leftEdge && sample <= rightEdge)
                    bins[binNum - 1]++;
            }
            else if (sample > leftEdge && sample <= rightEdge)
            {
                bins[binNum]++;
            }
        }
    }

    for (int i = 0; i < BIN_COUNT; ++i)
        std::cout << bins[i] << " " << std::flush;

    std::cout << std::endl << std::endl;

    return 0;
}
4

1 に答える 1

3

エッジが常に昇順であると仮定すると、必要なのは次のとおりです。

     unsigned int bin;
    for (unsigned int sampleNum = 0; sampleNum < SAMPLE_COUNT; ++sampleNum)
    {
           const int sample = data0[sampleNum];
           bin = BIN_COUNT;
           for (unsigned int binNum = 0; binNum < BIN_COUNT; ++binNum)  {
                 const int rightEdge = binranges[binNum];
                 if (sample <= rightEdge) {
                    bin = binNum;
                    break;
                }
           }
           bins[bin]++;
      }

ただし、このコードを機能させるには、最初のエッジと等しいかそれ以下の値に対してもう 1 つのビンを追加する必要があります ( 0)。

合理的な理由は、n 個のセパレーターがある場合、n+1 個の間隔があるということです。

于 2013-03-04T23:39:22.283 に答える