Использование np.bincount
.Вычисляет обе суммы ('foo' и 'bar').
sum_foo, sum_bar = np.bincount(np.char.equal(b, 'bar'), a)
sum_foo
# 28.0
sum_bar
# 713.0
Примечание np.char.equal
работает как со списками, так и с массивами.Если b является массивом, тогда вместо него можно использовать b == 'bar'
и он немного быстрее.
Время:
Несмотря на то, что это вычисляет обе суммы, на самом деле это довольно быстро:
timeit(lambda: np.bincount(b == 'bar', a))
# 2.406161994993454
Сравните, например, с методом маскировки пустышек:
timeit(lambda: a[b == 'bar'].sum())
# 5.642918559984537
На больших массивах маскирование становится немного быстрее, что ожидается, поскольку bincount
выполняет в два раза большую работу.Тем не менее, bincount
занимает меньше, чем двукратное время, поэтому, если вам понадобятся обе суммы ('foo' и 'bar'), bincount
все еще быстрее.
aa = np.repeat(a, 1000)
bb = np.repeat(b, 1000)
timeit(lambda: aa[bb == 'bar'].sum(), number=1000)
# 0.07860603698645718
timeit(lambda:np.bincount(bb == 'bar', aa), number=1000)
# 0.11229897901648656