4

これはC#よりも数学の方が多いと思います。float値の配列があり、ほとんどの値は数少ない密集した範囲の1つに属しています。次に例を示します(下限= 0、上限= 612):

3.4,5.0,6.1, 
144.0,144.14,145.0,147.0, 
273.77,275.19,279.0, 
399.4,399.91,401.45, 
533.26,537.0,538.9

これは16個の値の単一の配列であり、それらを分離してそれらの「グループ」を示しています。私がする必要があるのは、Linqまたは手動ループなどを使用して、それらを何らかの方法でグループ化し、それらの近い値が1つのグループに分類されるようにすることです。

399は401とは異なるグループ(上記の例では4番目のグループ)に分類されるため、10(または100)で除算するような単純な数学演算は機能しません。別のアプローチは、ある種のヒストグラムを作成することですが、ここでは簡単なものを探しています。どんな助けでも大歓迎です。

4

2 に答える 2

1

GroupByカスタム比較機能を使用したクラスタリングの別のアイデア

var numbers = new float[]
    {
       3.4f, 5.0f, 6.1f, 144.0f, 144.14f, 145.0f, 
       147.0f, 273.77f, 275.19f, 279.0f, 399.4f, 399.91f, 401.45f,
       49, 50, 51,
       533.26f, 537.0f, 538.9f
    };

foreach (var group in numbers.GroupBy(i => i, new ClosenessComparer(4f)))
    Console.WriteLine(string.Join(", ", group));

そして習慣ClosenessComparer

public class ClosenessComparer : IEqualityComparer<float>
{
    private readonly float delta;

    public ClosenessComparer(float delta)
    {
        this.delta = delta;
    }

    public bool Equals(float x, float y)
    {
        return Math.Abs((x + y)/ 2f - y) < delta;
    }

    public int GetHashCode(float obj)
    {
        return 0;
    }
}

そして出力:

1: 3,4 5 6,1
2: 144 144,14 145 147
3: 273,77 275,19 279
4: 399,4 399,91 401,45
6: 49 50 51
5: 533,26 537 538,9
于 2012-09-11T07:09:56.013 に答える
1

要素が前の値の特定のデルタ(デフォルトでは4)内にある場合に要素をグループ化するメソッドは次のとおりです。

IEnumerable<IEnumerable<double>> GetClusters(IEnumerable<double> data,
                                             double delta = 4.0)
{
    var cluster = new List<double>();
    foreach (var item in data.OrderBy(x=>x))
    {
        if (cluster.Count > 0 && item > cluster[cluster.Count - 1] + delta)
        {
            yield return cluster;
            cluster = new List<double>();
        }
        cluster.Add(item);
    }
    if (cluster.Count > 0)
        yield return cluster;
}

に使用するものを変更することで、アルゴリズムを微調整できますcluster[cluster.Count - 1] + delta。たとえば、

  • cluster[0] + delta-クラスターの最初の要素からのデルタ
  • cluster.Average() + delta-これまでのクラスターの平均からのデルタ
  • cluster[cluster.Count / 2] + delta-これまでのクラスターの中央値からのデルタ
于 2012-09-11T06:52:25.543 に答える