Wie führe ich eine elementweise Multiplikation zweier Listen durch?

137

Ich möchte eine elementweise Multiplikation durchführen, um zwei Listen in Python mit dem Wert zu multiplizieren, wie wir es in Matlab tun können.

So würde ich es in Matlab machen.

a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]

Ein Listenverständnis würde 16 Listeneinträge für jede Kombination x * yvon xvon aund yvon ergeben b. Unsicher, wie dies abgebildet werden soll.

Wenn jemand interessiert ist, warum, habe ich einen Datensatz und möchte ihn mit multiplizieren Numpy.linspace(1.0, 0.5, num=len(dataset)) =).

xxjjnn
quelle
4
Warum fragst du das, wenn du schon jetzt über Numpy bist?
Pwuertz
2
Übrigens ist dies eine elementweise Multiplikation, dies ist kein Punktprodukt.
Pwuertz
3
Alternative: Karte (Lambda x, y: x * y, Liste1, Liste2) #derp ...
xxjjnn

Antworten:

284

Verwenden Sie ein Listenverständnis gemischt mit zip():.

[a*b for a,b in zip(lista,listb)]
gahooa
quelle
9
Auf der anderen Seite wäre das OP gut beraten, Numpy zu verwenden, wenn sie etwas anderes als den trivialen Fall hier tun wollen.
Henry Gomersall
1
Unter Python 2 könnte izip () die bessere Wahl sein.
Yak
23
Sie können auch verwenden map(lambda x,y:x*y,lista,listb).
mbomb007
Wie würde sich die Antwort ändern, wenn wir anstelle listbeiner Liste von Elementen des Typs listbangegeben werden und wir operieren müssen, um eine einzelne Liste zu erhalten? Ex. (x, pi, e) mit [(4, 5, 2), (1, 2, 4), (4, 5, 6), (1, 1, 2), (3, 3, 4)], wenn genommen (x, pi, e) mit (4, 5, 2) und dann (x, pi, e) mit (1, 2, 4) ... so weiter.
Gxyd
@gxyd Sie sollten eine separate Frage stellen
mbomb007
87

Da Sie bereits verwenden numpy, ist es sinnvoll, Ihre Daten in einem numpyArray anstatt in einer Liste zu speichern . Sobald Sie dies tun, erhalten Sie Dinge wie elementweise Produkte kostenlos:

In [1]: import numpy as np

In [2]: a = np.array([1,2,3,4])

In [3]: b = np.array([2,3,4,5])

In [4]: a * b
Out[4]: array([ 2,  6, 12, 20])
NPE
quelle
1
Vielleicht nicht die wissenschaftlichste, aber ich habe dies gegen Gahooas Antwort mit timeit abgestimmt. Numpy ist tatsächlich etwas langsamer als die Zip-Methode.
Chase Roberts
1
In meinem Fall, in dem die Listen Binärwerte enthielten, war die Numpy-Lösung viel schneller als die Verwendung von izip.
Serendipity
Für andere, die über eine Google-Suche hierher kommen, habe ich unten einen Zeitvergleich aufgeführt.
Paddyg
31

Verwenden Sie np.multiply (a, b):

import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)
Brisa
quelle
21

Sie können versuchen, jedes Element in einer Schleife zu multiplizieren. Die kurze Hand dafür ist

ab = [a[i]*b[i] for i in range(len(a))]
Nate
quelle
Willkommen bei Stackoverflow! Von Nur-Code-Antworten wird im Allgemeinen abgeraten. Bitte fügen Sie eine Erklärung hinzu, wie dies die Frage des Fragestellers löst.
Corley Brigman
7
@ CorleyBrigman Ich bin anderer Meinung; Es gibt kaum einen Unterschied zwischen der Antwort "Hier ist eine Möglichkeit, dies zu tun: <code>" und nur "<code>". In dieser besonderen Situation gibt es nur wenig zu erklären als "Dieser Code löst Ihr Problem".
Eisbäume
4
@ CorleyBrigman Ich bin anderer Meinung; Ein Beispiel Daten mit der Anzeige der Ergebnisse wäre tatsächlich hilfreicher
Tjorriemorrie
2
Auf diese Weise würde ein C-, C ++ - oder Java-Programmierer, der ein Python-Neuling ist, das Problem lösen. Die akzeptierte Antwort ist idiomatisches Python.
David Cullen
@Tjorriemorrie Die Ergebnisse sind klar, da sie in der Frage ausdrücklich angefordert werden. Vielleicht könnte eine Erklärung, wie Listenverständnis funktioniert, nett sein oder erwähnen, dass dies das Listenverständnis nutzt, und dann kann jeder das nachschlagen, wenn er es nicht weiß.
xuiqzy
10

Noch eine Antwort:

-1... erfordert Import
+1... ist sehr gut lesbar

import operator
a = [1,2,3,4]
b = [10,11,12,13]

list(map(operator.mul, a, b))

Ausgänge [10, 22, 36, 52]

Petr Vepřek
quelle
Wenn Sie Karte kennen, ist dies eine wirklich lesbare Lösung! Hat der Import negative Konsequenzen, außer dass er oben in der Datei steht? (Editoren können Importe ausblenden, wenn sie wollen) Soweit ich sehen kann, sollte es in jeder Python 2 und 3 Version verfügbar sein!
xuiqzy
9

Ziemlich intuitive Vorgehensweise:

a = [1,2,3,4]
b = [2,3,4,5]
ab = []                        #Create empty list
for i in range(0, len(a)):
     ab.append(a[i]*b[i])      #Adds each element to the list
Rollkragen
quelle
9

Sie können mit multiplizieren lambda

foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)
Benjamin
quelle
4

Bei großen Listen können wir dies iterativ tun:

product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])

product_iter_object.next() gibt jedes Element in der Ausgabeliste an.

Die Ausgabe wäre die Länge der kürzeren der beiden Eingabelisten.

aady
quelle
4

Erstellen Sie eine Reihe von Einsen. Multiplizieren Sie jede Liste mit dem Array. Array in eine Liste konvertieren

import numpy as np

a = [1,2,3,4]
b = [2,3,4,5]

c = (np.ones(len(a))*a*b).tolist()

[2.0, 6.0, 12.0, 20.0]
Präsenz
quelle
3

Die Antwort von gahooa ist richtig für die Frage, wie sie in der Überschrift formuliert ist. Wenn die Listen jedoch bereits ein Numpy-Format haben oder größer als zehn sind, ist es VIEL schneller (3 Größenordnungen) und besser lesbar, eine einfache Numpy-Multiplikation durchzuführen, wie von vorgeschlagen NPE. Ich bekomme diese Zeiten:

0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 4, a = np.arange(N), c = a * b
0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 40, a = np.arange(N), c = a * b
0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0020ms -> N = 400, a = np.arange(N), c = a * b

dh aus dem folgenden Testprogramm.

import timeit

init = ['''
import numpy as np
N = {}
a = {}
b = np.linspace(0.0, 0.5, len(a))
'''.format(i, j) for i in [4, 40, 400] 
                  for j in ['[i for i in range(N)]', 'np.arange(N)']]

func = ['''c = [a*b for a,b in zip(a, b)]''',
'''c = a * b''']

for i in init:
  for f in func:
    lines = i.split('\n')
    print('{:6.4f}ms -> {}, {}, {}'.format(
           timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))
paddyg
quelle
3

Kann Aufzählung verwenden.

a = [1, 2, 3, 4]
b = [2, 3, 4, 5]

ab = [val * b[i] for i, val in enumerate(a)]
SuperNova
quelle
3

Die mapFunktion kann hier sehr nützlich sein. Verwenden vonmap wir jede Funktion auf jedes Element einer Iterable anwenden.

Python 3.x.

>>> def my_mul(x,y):
...     return x*y
...
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>>
>>> list(map(my_mul,a,b))
[2, 6, 12, 20]
>>>

Natürlich:

map(f, iterable)

ist äquivalent zu

[f(x) for x in iterable]

So können wir unsere Lösung erhalten über:

>>> [my_mul(x,y) for x, y in zip(a,b)]
[2, 6, 12, 20]
>>>

In Python map()bedeutet 2.x : Wenden Sie eine Funktion auf jedes Element einer Iterable an und erstellen Sie eine neue Liste. In Python 3.xmap Iteratoren anstelle von Listen.

Stattdessen my_mulkönnten wir verwenden mul Operator verwenden

Python 2.7

>>>from operator import mul # import mul operator
>>>a = [1,2,3,4]
>>>b = [2,3,4,5]
>>>map(mul,a,b)
[2, 6, 12, 20]
>>>

Python 3.5+

>>> from operator import mul
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>> [*map(mul,a,b)]
[2, 6, 12, 20]
>>>

Bitte beachten Sie, dass map()wir , da wir einen Iterator *erstellen , den iterierbaren Entpackungsoperator verwenden, um eine Liste zu erhalten. Der Auspackansatz ist etwas schneller als der listKonstruktor:

>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>
sg7
quelle
1

So pflegen Sie den Listentyp in einer Zeile (natürlich nach dem Importieren von numpy als np):

list(np.array([1,2,3,4]) * np.array([2,3,4,5]))

oder

list(np.array(a) * np.array(b))
mächtig
quelle
0

Sie können dies für Listen gleicher Länge verwenden

def lstsum(a, b):
    c=0
    pos = 0
for element in a:
   c+= element*b[pos]
   pos+=1
return c
WOX GAMER
quelle