Python; самый эффективный способ реализовать поэлементное векторное умножение - PullRequest
1 голос
/ 12 января 2012

Мне нужен функция-агрегатор, которая бы сводила два списка к одному общему числу.'Items' должен быть вектором логических значений.

Итак, я написал эти функции:

def element_wise_multiplication(weights, items):
    return map(lambda x, y: x * y, weights, items)

def total(weights, items):
    return sum(element_wise_multiplication(weights, items))

Они выглядят нормально для меня, но проблема в том, что профилировщик показал, что строка сЛямбда в нем отвечает за 95% времени выполнения, поэтому ее производительность в значительной степени неприемлема.

Какой самый эффективный способ ее реализации?

PS Мне известны массивы NumPy, но я бы хотел использовать PyPy на этом.Или использование этого не стоит в этом случае?

Ответы [ 3 ]

3 голосов
/ 12 января 2012

Вы можете позаботиться об этом с помощью генератора следующим образом:

from itertools import izip
value = sum((x * y) for x, y in izip(weights, items))

izip выполняет то же самое, что и встроенный zip, но без перегрузки памяти.

2 голосов
/ 12 января 2012

Хотя вы упоминаете, что не хотите использовать numpy в этом случае, возможно, стоит посмотреть на разницу в скорости.

Лучшим решением, отличным от numpy, является генератор, использующий izip, который незначительно превосходит zip.

    In [31]: %timeit sum(x*y for x,y in zip(weights,items))
    10000 loops, best of 3: 158 us per loop

    In [32]: %timeit sum(x*y for x,y in izip(weights,items))
    10000 loops, best of 3: 125 us per loop

Однако, когда мы используем массивы numpy, мы получаем:

    In [33]: %timeit (np_weights,np_items).sum()
    100000 loops, best of 3: 9.08 us per loop

Полное решение в 14 раз быстрее. Если это действительно узкое место в вашем коде, тогда numpy - это то, что нужно.

1 голос
/ 12 января 2012

попробуйте только это:

def total(weights, items):
   return sum (x * y for x, y in zip(weights, items))  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...