1

他の質問に助けられた後、VB.NET DataTable の一連のデータポイントで動作するノイズ削減アルゴリズムをプログラムしようとしています。yCoord基本的には、座標値 (たとえば) としきい値平滑化値 ( )の 2 つの整数をNoiseThresh取り、範囲内の値の平均を取り、(yCoord - NoiseThresh, yCoord + NoiseThresh)その数値を配列に格納します。このプロセスを列ごとに繰り返して (この例では)、最終的に平均値の 1 次元配列が得られます。私の質問は次のとおりです。

1) 今言ったことは意味がありましたか ;)、そして
2) 誰かコードを手伝ってくれませんか? データベースを扱った経験はほとんどありません。

ありがとう!

私がやろうとしていることの例:

//My data (pretend it's a database)
1  4  4  9  2  //yCoord would equal 5
6  3  8  12 3  //yCoord = 4
8  3 -2  2  0  //yCoord = 3
9 17  3  7  5  //yCoord = 2
4  1  0  9  7  //yCoord = 1

//In this example, my yCoord will equal 3 and NoiseThresh = 1

//For the first column
    Array(column1) = //average of the set of numbers centered at yCoord = 3 _
//(in this case 8) and the NoiseThresh=1 number on either side (here 6 & 9)
//For the second column
    Array(column2) = //average of the numbers 3,3,17 for example
    //etc., etc.,

これは大規模なデータ セット (通常の数値は yCoord=500、NoiseThresh = 50、配列の長さ = 1092) に対して実行されるため、数値を手動で入力する可能性はありません。

これが私の質問を明確にするのに役立つことを願っています!

PS: はい、// が VB.NET のコメントではないことはわかっています。

4

1 に答える 1

1

範囲の部分 (NoiseThresh など) をまだ理解していないことを認めなければなりませんが、これが始まりです。

Dim averages = (From col In tbl.Columns.Cast(Of DataColumn)()
               Select tbl.AsEnumerable().
                      Average(Function(r) r.Field(Of Int32)(col.ColumnName))).
               ToArray()

の各列のすべての平均を計算し、結果からDataTableを作成しますDouble()(平均は、整数で使用された場合でも小数点以下の桁数になる可能性があります)。

編集:あなたの例で、範囲部分を理解しました。したがって、基本的yCordには行インデックス(+1)でnoiseThreasあり、行範囲(+/- n行)です。

次に、これにより正しい結果が得られます(いくつかのコードコメントを作成しました):

Dim yCord = 2 ' the row index(-1 since indices are 0-based) '
Dim noiseThresh = 1 ' +/- row '
' reverse all rows since your sample begins with index=5 and ends with index=1 '
Dim AVGs As Double() = (
    From colIndex In Enumerable.Range(0, tbl.Columns.Count)
    Select tbl.AsEnumerable().Reverse().
    Where(Function(r, index) index >= yCord - noiseThresh _
                     AndAlso index <= yCord + noiseThresh).
    Average(Function(r) r.Field(Of Int32)(colIndex))).ToArray()

このLINQクエリの最も重要な部分はWhere. に範囲を適用しますIEnumerable(of DataRow)。次に、すべての列についてこれらの行の平均を計算しています。最後のステップは、クエリをDouble().

結果:

    (0) 7.666666666666667   Double  => (6+8+9)/3
    (1) 7.666666666666667   Double  => (3+3+17)/3
    (2) 3.0                 Double  => (8-2+3)/3
    (3) 7.0                 Double  => (12+2+7)/3
    (4) 2.6666666666666665  Double  => (3+0+5)/3

編集2

最後に一つだけ。他の軸についても同じことを行うには、xとyと行と列を切り替えるだけだと思いますか?

それほど単純ではありません。しかし、自分で見てください:

Dim noiseThresh = 1 ' +/- column '
Dim xCord = 2 ' the column index(-1 since indices are 0-based) '
' assuming that your x-cords now start with index=0 and ends with tbl.Column.Count-1 '
Dim AVGs As Double() = (
    From rowIndex In Enumerable.Range(0, tbl.Rows.Count)
    Select tbl.Columns.Cast(Of DataColumn)().
    Where(Function(c, colIndex) colIndex >= xCord - noiseThresh _
                        AndAlso colIndex <= xCord + noiseThresh).
    Average(Function(c) tbl.Rows(rowIndex).Field(Of Int32)(c.Ordinal))).ToArray()

結果:

    (0) 5.666666666666667   Double  => (4+4+9)/3
    (1) 7.666666666666667   Double  => (3+8+12)/3
    (2) 1.0                 Double  => (3-2+2)/3
    (3) 9.0                 Double  => (17+3+7)/3
    (4) 3.3333333333333335  Double  => (1+0+9)/3
于 2012-06-21T07:46:17.633 に答える