Эффективно суммировать небольшой массив numpy, транслируемый по огромному массиву numpy?

Я хочу вычислить индексированную сумму весов по большому (1 000 000 x 3000) логический массив numpy. Большой логический массив изменяется нечасто, но веса приходят во время запроса, и мне нужны ответы очень быстро, без копирования всего большого массива или расширения малый массив весов до размера большого массива.

В результате должен получиться массив из 1 000 000 записей, каждая из которых имеет сумма элементов массива весов, соответствующих True этой строки ценности.

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

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

Я новичок в numpy, и мне это нравится, но я собираюсь отказаться от него ради эта конкретная проблема. Я изучил достаточно numpy, чтобы знать, чтобы остаться подальше от всего, что зацикливается на питоне.

Следующим моим шагом будет написание этой подпрограммы на C (с добавленным преимущество в том, что я могу экономить память, используя биты вместо байтов, путь.)

Если только один из вас, гуру тупых, не сможет спасти меня от cython?

from numpy import array, multiply, sum

# Construct an example values array, alternating True and False.
# This represents four records of three attributes each:
#    array([[False,  True, False],
#           [ True, False,  True],
#           [False,  True, False],
#           [ True, False,  True]], dtype=bool)
values = array([(x % 2) for x in range(12)], dtype=bool).reshape((4,3))

# Construct example weights, one for each attribute:
#    array([1, 2, 3])
weights = array(range(1, 4))

# Create expensive NEW array with the weights for the True attributes.
# Broadcast the weights array into the values array.
#    array([[0, 2, 0],
#           [1, 0, 3],
#           [0, 2, 0],
#           [1, 0, 3]])
weighted = multiply(values, weights)

# Add up the weights:
#    array([2, 4, 2, 4])
answers = sum(weighted, axis=1)

print answers

# Rejected masked_array solution is too expensive (and oddly inverts
# the results):
masked = numpy.ma.array([[1,2,3]] * 4, mask=values)
8
задан tillsten 19 April 2012 в 21:00
поделиться