【问题标题】:C# Multiply Each row of array by set of factorsC#将数组的每一行乘以一组因子
【发布时间】:2019-05-30 19:21:08
【问题描述】:

我有一个多维数组,我想将它的每一行乘以一个包含因子的单维数组来创建一个新的多维数组。但是,多维数组中的行数会随着一次运行而变化,因此我需要一种方法来循环乘法遍历多维数组的每一行,直到到达最后一行。

这是一个简单的例子,我有多维数组: { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 12} }

我想将每一行乘以: {0.5、0.4、0、0.8}

得到: { { 1*0.5, 2*0.4, 3*0, 4*0.8}, { 5*0.5, 6*0.4, 7*0, 8*0.8}, { 9*0.5, 10*0.4, 11*0, 12*0.8} }

我尝试使用示例代码在 for 循环中使用 .Length。

double [] factors = {0.5, 0.4, 0, 0.8};

int [,] myarray = new int [3,4] {
{ 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9, 10, 11, 12}
};

double [] output = new double[myarray.Length];
for(int i = 0; i < myarray.Length; ++i)
    output[i] = myarray[i] * factors;

我收到语法错误,扩展方法“长度”不能应用于 int 类型,并且使用 [] 进行索引也不能应用于 int 类型。

【问题讨论】:

  • 您需要创建第二个(内部)循环,遍历factors 的元素。 C# 不能自己做向量乘法。
  • 您可能需要考虑使用锯齿状数组int[][] 而不是二维数组int[,]。使用二维数组时,您需要使用GetLength(int dimention) 来获取给定维度的大小。
  • 此外,您的代码会产生一个错误,即为 myarray 使用错误的索引数量,而不是有关将 Length 应用于 int 的错误。确保发布与代码匹配的错误。
  • 如果您将代码更改为output[i] = myarray[i/4, i%4] * factors[i%4];,您将获得结果,但在一个长度为 12 的数组中。

标签: c# arrays multiplication


【解决方案1】:

我建议使用一个参差不齐的数组。存在多维数组,但支持很差,几乎没有人使用它们。如果使用锯齿状数组,可以更简洁。更重要的是,您可以更加有意

double[][] myArray = getMeSomeData();
double[]   factors = getMeSomeRowFactors();

foreach (var row in myArray)
{
  MultiplyRow(row, factors)
}

. . .

void MultiplyRow( double[] row, double[] factors )
{
  for ( int col = 0 ; col < row.length ; ++col )
  {
    row[col] = row[col] * factors[col];
  }
}

甚至更好:使用 Linq:

double[][] myArray = getMeSomeData();
double[]   factors = getMeSomeRowFactors();

myArray = myArray
          .Select( row => row.Select( (cell, i) => cell * factors[i] ).ToArray() )
          .ToArray()
          ;

甚至[可以说]更好;

double[][] myArray = getMeSomeData();
double[]   factors = getMeSomeRowFactors();

myArray = myArray
          .Select( Multiply(factors) )
          .ToArray()
          ;

. . .
Func<double,int,double[]> Multiply( double[] factors )
{
  return (cell, i) => cell * factors[i];
}

【讨论】:

    【解决方案2】:

    我不确定你是否觉得它有用,但你可以通过使用 MathNet.Numerics 来实现它:

    PM> 安装包 MathNet.Numerics

    using MathNet.Numerics.LinearAlgebra.Double;
    using System.Linq;
    
    ...
    
    var myarray = new double[3, 4]
    {
        { 1, 2, 3, 4},
        { 5, 6, 7, 8},
        { 9, 10, 11, 12}
    };
    
    var factors = new double[4] { 0.5, 0.4, 0, 0.8 };
    
    var matrix1 = Matrix.Build
        .DenseOfArray(myarray);
    var matrix2 = Matrix.Build
        .DenseOfRows(Enumerable.Repeat(factors, matrix1.RowCount));
    
    var res = matrix1.PointwiseMultiply(matrix2).ToArray();
    

    【讨论】:

      【解决方案3】:

      可以使用GetLength的方法获取每个维度的长度:

      double[,] output = new double[myarray.GetLength(0), myarray.GetLength(1)];
      for (int i = 0; i < myarray.GetLength(0); i++)
      {
          for (int j = 0; j < myarray.GetLength(1); j++)
          {
              output[i, j] = myarray[i, j] * factors[j];
          }
      }
      

      如果您的数组很大,您可以使用 PC 的所有处理器/内核来加快计算速度:

      Parallel.For(0, myarray.GetLength(0), i =>
      {
          for (int j = 0; j < myarray.GetLength(1); j++)
          {
              output[i, j] = myarray[i, j] * factors[j];
          }
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-03
        • 1970-01-01
        • 2015-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-15
        • 1970-01-01
        相关资源
        最近更新 更多