C # Умножить каждую строку массива на множество факторов - PullRequest
0 голосов
/ 30 мая 2019

У меня есть многомерный массив, и я хочу умножить каждую его строку на одномерный массив, содержащий факторы, чтобы создать новый многомерный массив.Тем не менее, количество строк в многомерном массиве будет варьироваться от одного прогона к следующему, поэтому мне понадобится способ циклического перемножения каждой строки многомерного массива до достижения последней строки.

Вот простой пример, у меня есть многомерный массив: {{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, используя пример кода.

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.

Ответы [ 3 ]

1 голос
/ 31 мая 2019

Я бы предложил рваный массив.Существуют многомерные массивы, но они плохо поддерживаются и почти никто не использует их.Если вы используете зубчатый массив, вы можете быть более кратким.Что еще более важно, вы можете быть более преднамеренным об этом:

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];
}
0 голосов
/ 31 мая 2019

Вы можете получить длину каждого измерения, используя метод 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];
    }
}

Если ваш массив огромен, вы можете ускорить вычисления, используя все процессоры / ядра вашего ПК:

Parallel.For(0, myarray.GetLength(0), i =>
{
    for (int j = 0; j < myarray.GetLength(1); j++)
    {
        output[i, j] = myarray[i, j] * factors[j];
    }
});
0 голосов
/ 31 мая 2019

Я не уверен, что вы найдете это полезным, но вы можете достичь этого, используя 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...