сумма продуктов для нескольких списков в Python - PullRequest
9 голосов
/ 03 октября 2010

Попытка имитировать функцию Excel SUMPRODUCT:

SUMPRODUCT(v1, v2, ..., vN) =
    v1[0]*v2[0]*...*vN[0] + v1[1]*v2[1]*...*vN[1] + ... + v1[n]*v2[n]*...*vN[n]

где n - количество элементов в каждом векторе.

Это похоже на скалярное произведение, но для нескольких векторов. Я прочитал очень подробное обсуждение обычного точечного произведения, но я не знаю, как точно распространить его на несколько векторов. Для справки, я копирую предложенный оптимизированный код, который я перенес (тривиально) в Python 3. Кстати, для точечного продукта последний подход все еще выигрывает в P3K.

def d0(v1,v2):
    """                                                                                                     
    d0 is Nominal approach:                                                                                 
    multiply/add in a loop                                                                                  
    """
    out = 0
    for k in range(len(v1)):
        out += v1[k] * v2[k]
    return out

def d1(v1,v2):
    """                                                                                                     
    d1 uses a map                                                                        
    """
    return sum(map(mul,v1,v2))

def d3(v1,v2):
    """                                                                                                     
    d3 uses a starmap (itertools) to apply the mul operator on an zipped (v1,v2)                           
    """
    return sum(starmap(mul,zip(v1,v2)))

Ответы [ 3 ]

19 голосов
/ 03 октября 2010
import operator

def sumproduct(*lists):
    return sum(reduce(operator.mul, data) for data in zip(*lists))

для питона 3

import operator
import functools

def sumproduct(*lists):
    return sum(functools.reduce(operator.mul, data) for data in zip(*lists))
7 голосов
/ 27 октября 2016

А как насчет старого доброго понимания списка?(Как уже упоминалось @Turksarama, это работает только для двух списков)

sum([x * y for x, y in zip(*lists)])

Тестирование в Python 3.6:

In [532]: import random

In [534]: x = [random.randint(0,100) for _ in range(100)]

In [535]: y = [random.randint(0,100) for _ in range(100)]

In [536]: lists = x, y

Использование списочных представлений

In [543]: %timeit(sum([x * y for x, y in zip(*lists)]))
8.73 µs ± 24.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Обратите внимание, что«кортеж» понимает медленнее

In [537]: %timeit(sum(x * y for x, y in zip(*lists)))
10.5 µs ± 170 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Использование map

In [539]: %timeit(sum(map(lambda xi, yi: xi * yi, x, y)))
12.3 µs ± 144 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Использование functools.reduce

In [542]: %timeit(sum(functools.reduce(operator.mul, data) for data in zip(*lists)))
38.6 µs ± 330 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
7 голосов
/ 29 июля 2015

Сопоставьте список, чтобы создать список продуктов, а затем суммируйте его.

Это можно сделать в одну строку:

sum(map(lambda Xi, Yi: Xi * Yi, ListX, ListY))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...