Как получить сумму значений определенных элементов массива NumPy? - PullRequest
0 голосов
/ 07 августа 2020

У меня три массива NumPy. Два массива (скажем, a и b) содержат левую и правую границу номера столбца третьего массива (c), который должен быть обработан, т.е. имеют суммированные значения его элементов в пределах границ. Как мне сделать это в NumPy? В настоящее время я сделал это с помощью Python вот так:

>>> a = np.array([ 3,  7, 11])
             
>>> b= np.array([25, 21, 17])
             
>>> c = np.arange(90).reshape(3,30)
             
>>> c
             
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
       [30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
        46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
       [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
        76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89]])

>>> row=0
                
>>> for l, r in zip(a,b):
    print( sum( c[ row, l:r ] ) )
    row+=1

                
297
609
441
>>> sum([3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23, 24,])
                
297
>>> sum([37, 38, 39, 40, 41, 42, 43, 44, 45,
        46, 47, 48, 49, 50])
                
609
>>> sum([71, 72, 73, 74, 75,
        76])
                
441
>>> 

Ответы [ 2 ]

1 голос
/ 07 августа 2020
idx = np.repeat(np.arange(c.shape[1])[None, :], c.shape[0], axis=0)
(c * ((idx >= a[:, None]) & (idx < b[:, None]))).sum(axis=1)
# output: array([297, 609, 441])

Что здесь происходит:

  1. Создайте плитку диапазонов: [[0, 1, ... n], [0, 1, ..., n] , ...]
  2. построчно установить маску для элементов, которые меньше b и больше a. a[:, None] просто добавляет измерение, numpy затем транслирует этот массив в соответствии с формой диапазона.
  3. умножает c на эту маску. Логические значения, интерпретируемые как целые числа, равны 0 или 1, поэтому все, кроме элементов для суммирования, превращается в ноль
  4. Сумма по строкам

PS. На объяснение уходит больше времени, чем на написание кода. Кроме того, поскольку диапазоны, устанавливаемые парами из a, b, имеют произвольную длину, мы не можем хранить их в собственных структурах данных numpy. Вот почему здесь приходится играть с масками

0 голосов
/ 07 августа 2020

Другая версия l oop:

[c[n,np.s_[i:j]].sum() for n,(i,j) in enumerate(zip(a,b))]

вывод:

[297, 609, 441]

Я бы рекомендовал для небольших c использовать другой ответ, а для больших c используйте этот ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...