1

在我的其他问题得到帮助后,我正在尝试编写一种降噪算法,该算法适用于 VB.NET DataTable 中的一组数据点。基本上,我想取两个整数,一个坐标值(yCoord例如)和一个平滑阈NoiseThresh(yCoord - NoiseThresh, yCoord + NoiseThresh)(我会为每一列(在这个例子中)重复这个过程,最终得到一个一维的平均值数组。我的问题是:

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 回答