numpy: как векторизовать цикл агрегации [duplicate]

13
задан fideli 5 January 2010 в 06:37
поделиться

4 ответа

После выполнения

bbins=np.bincount(b)

, почему бы не сделать:

a[:len(bbins)] += bbins

(Отредактировано для дальнейшего упрощения.)

5
ответ дан Alok Singhal 26 August 2018 в 16:07
поделиться
  • 1
    Не будет ли это медленнее, когда b содержит только несколько больших номеров бинов? – Eric Lebigot 5 January 2010 в 10:11
  • 2
    Да, в этом случае он будет медленнее, чем простой цикл Python, но все же быстрее, чем код OP. Я сделал быстрый тест времени с b = [99999, 99997, 99999] и a = np.zeros(1000, 'int'). Сроки: OP: 2,5 мс, мой: 495 us, простой цикл: 84 us. – Alok Singhal 5 January 2010 в 16:23
  • 3
    Это хорошо работает. Простой цикл, как правило, был медленнее в моей программе. Благодарю. – fideli 5 January 2010 в 17:48
  • 4
    Есть ли аналогичный способ сделать это в многомерном случае? – ajwood 14 September 2011 в 22:43

Если b является небольшим поддиапазоном a, можно уточнить ответ Алока следующим образом:

import numpy as np
a = np.zeros( 100000, int )
b = np.array( [99999, 99997, 99999] )

blo, bhi = b.min(), b.max()
bbins = np.bincount( b - blo )
a[blo:bhi+1] += bbins

print a[blo:bhi+1]  # 1 0 2
1
ответ дан denis 26 August 2018 в 16:07
поделиться

В numpy> = 1.8 вы также можете использовать метод at добавления универсальной функции ('ufunc'). Как docs note :

Для добавления ufunc этот метод эквивалентен [индексам] + = b, за исключением того, что результаты накапливаются для элементов, которые индексируются больше чем один раз.

Итак, возьмем ваш пример:

a = np.zeros(6).astype('int')
b = [3, 2, 5, 2]

... затем ...

np.add.at(a, b, 1)

... оставит a как ...

array([0, 0, 2, 1, 0, 1])
13
ответ дан gojomo 26 August 2018 в 16:07
поделиться
  • 1
    Это решение является самым элегантным AFAIK! – Sibbs Gambling 28 June 2017 в 22:01

Почему нет?

for i in b:
    a[i] += 1
-4
ответ дан Luka Rahne 26 August 2018 в 16:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: