在LINQ C#中计算数组

时间:2015-07-09 15:03:35

标签: c# arrays linq

我想用linq用单个短语计算相关矩阵。我怎么能这样做(如果可能的话)?

假设我已经有一个名为volatilites的大小为N的数组,而返回是一个锯齿状数组,其中N个数组的大小都相同。

我也在使用:

using stats = MathNet.Numerics.Statistics.ArrayStatistics

这是我想在LINQ中创建的代码:

double[,] correlation_matrix = new double[N,N];
for (int i=0; i<N;i++){
    for (int j = i + 1; j < N; j++){
        correlation_matrix [i,j]= stats.Covariance(Returns[i], Returns[j]) / (volatilities[i] * volatilities[j]); // stores it to check values       
    }
}

谢谢!

2 个答案:

答案 0 :(得分:6)

如果你让自己有一个数组数组,你可以做

var correlation_matrix = 
    Returns.Select((r_i, i) => 
        Returns.Where((r_j, j) => j > i).Select((r_j, j) =>
            stats.Covariance(r_i, r_j) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();

如果您想使用范围(根据您的评论),您可以

var N = Returns.Length;
var correlation_matrix = 
    Enumerable.Range(0, N).Select(i => 
        Enumerable.Range(i + 1, N - i - 1).Select(j =>
            stats.Covariance(Returns[i], Returns[j]) / (volatilities[i] * volatilities[j])
        ).ToArray()
    ).ToArray();    

不要说你应该这样做。循环版本更具可读性和更高性能。

答案 1 :(得分:2)

每个OP请求Enumerable.Aggregate版本,结果为2d数组:

var correlation_matrix = 
   Enumerable.Range(0, N).Select(i => 
       Enumerable.Range(i + 1, N - i - 1).Select(j => 
         new {
            i, j, // capture location of the result
            Data = i + j } // compute whatever you need here
       )
   )
   .SelectMany(r => r) // flatten into single list
   .Aggregate(
       new double[N,N], 
       (result, item) => { 
           result[item.i, item.j] = item.Data; // use pos captured earlier
           return result; // to match signature required by Aggregate
        });

附注:这主要是使用LINQ而不是您应该在实际代码中使用的代码。

  • 代码必须将位置捕获到匿名对象中,从而导致大量不必要的分配
  • 我认为与普通for
  • 相比,此版本难以阅读