C#将数组的每一行乘以一组因子

C# Multiply Each row of array by set of factors

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

这是一个简单的例子,我有一个多维数组: { { 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;

我收到语法错误,扩展方法 'Length' 不能应用于 int 类型,并且使用 [] 的索引也不能应用于 int 类型。

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

来实现

PM> Install-Package 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();

我建议使用参差不齐的阵列。存在多维数组,但支持很差,几乎没有人使用它们。如果使用交错数组,可以更简洁。更重要的是,你可以更有意:

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];
}

可以通过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];
    }
}

如果你的数组很大,你可以使用你电脑的所有 processors/cores 来加速计算:

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