Pytanie Zwięzłe dodawanie wektorów w Pythonie? [duplikować]


To pytanie już zawiera odpowiedź:

Często robię wektorowe dodawanie list w Pythonie.

Przykład: Mam dwie takie listy:

a = [0.0, 1.0, 2.0]
b = [3.0, 4.0, 5.0]

Teraz chcę dodać b do a, aby uzyskać wynik a = [3.0, 5.0, 7.0].

Zwykle kończę w ten sposób:

a[0] += b[0]
a[1] += b[1]
a[2] += b[2]

Czy jest jakiś skuteczny, standardowy sposób robienia tego przy mniejszym pisaniu?

AKTUALIZACJA: Można założyć, że listy mają długość 3 i zawierają zmienne.


31
2018-05-10 11:05


pochodzenie




Odpowiedzi:


Nie sądzę, że znajdziesz szybsze rozwiązanie niż 3 sumy zaproponowane w pytaniu. Zalety numpy są widoczne przy większych wektorach, a także jeśli potrzebujesz innych operatorów. numpy jest szczególnie użyteczny w przypadku macierzy, co jest podstępem do zrobienia z listami Pythona.

Jeszcze inny sposób na zrobienie tego: D

In [1]: a = [1,2,3]

In [2]: b = [2,3,4]

In [3]: map(sum, zip(a,b))
Out[3]: [3, 5, 7]

Edytować: możesz również użyć izIP z itertools, zip wersji generatora

In [5]: from itertools import izip

In [6]: map(sum, izip(a,b))
Out[6]: [3, 5, 7]

29
2018-05-10 22:54



Śmieszny fakt: map przychodzi z zip funkcjonalność w zestawie. To pozwala powiedzieć map(operator.add, a, b) - Kos


Podczas gdy Numeric jest doskonały, a rozwiązania do rozumienia listów OK, jeśli rzeczywiście chciałeś stworzyć nową listę, jestem zaskoczony, że nikt nie zaproponował "jednego oczywistego sposobu na zrobienie tego" - prostego for pętla! Najlepiej:

for i, bi in enumerate(b): a[i] += bi

Również OK, kinda sorta:

for i in xrange(len(a)): a[i] += b[i]

31
2018-05-10 13:15



+1, to jest dla mnie oczywiste rozwiązanie. - Kiv
Szybszy niż inne rozwiązania, ale wciąż tylko o połowę szybszy. - Johan Kotlinski


Jeśli potrzebujesz wydajnej arytmetyki wektorowej, spróbuj Numpy.

>>> import numpy
>>> a=numpy.array([0,1,2])
>>> b=numpy.array([3,4,5])
>>> a+b
array([3, 5, 7])
>>> 

Lub (dzięki, Andrew Jaffe),

>>> a += b
>>> a
array([3, 5, 7])
>>> 

30
2018-05-10 11:21



nb. OP chce + = b, naprawdę - zobacz moją odpowiedź, poniżej! ;-) - Andrew Jaffe
Wygląda to na dobry sposób na zapisywanie na klawiaturze, ale nie podoba mi się to, że dodaje zależność i jest trzy razy wolniejsza od oryginalnego kodu. - Johan Kotlinski


Jeśli uważasz, że Numpy jest przesadny, powinno to być naprawdę szybkie, ponieważ ten kod działa w czystej C (map() i __add__() są bezpośrednio implementowane w C):

a = [1.0,2.0,3.0]
b = [4.0,5.0,6.0]

c = map(float.__add__, a, b)

Lub alternatywnie, jeśli nie znasz typów na liście:

import operator
c = map(operator.add, a, b)

15
2018-05-10 17:58



To naprawdę fajna odpowiedź, ale niestety trzy razy wolniejsza od oryginalnego kodu. - Johan Kotlinski
To mnie naprawdę zaskakuje. Przynajmniej pierwsza wersja powinna być szybsza. Może to tylko szybciej, jeśli masz większe listy. - Georg Schölly
Spójrz na moduł operatora. Możesz po prostu użyć operator.add. - schlamar
@schlamar: Zmieniono odpowiedź. Dzięki. - Georg Schölly
+1 dla operator.add. Ponadto w języku Python 3 map tworzy obiekt mapy, a nie listę. Więc właściwym rozwiązaniem byłoby c = list(map(operator.add, a, b)). - rlat


Co powiesz na to:

a = [x+y for x,y in zip(a,b)]

11
2018-05-10 11:09



+1, ale to zadziała tylko wtedy, gdy listy mają ten sam rozmiar. izip_longest o wartości zip 0, jeśli nie zawsze są tego samego rozmiaru - Nadia Alramli
Miło, ale nie oszczędza dużo pisania, a oryginalny kod jest ponad trzy razy szybszy. - Johan Kotlinski
@ kotlinski- hmm, masz rację - Nadia Alramli
kogo to obchodzi około 3? jak wpisać 100 przedmiotów? - SilentGhost
cóż, jeśli chcesz wiedzieć, jak sumować dwie listy o długości trzech par, to powinieneś wyraźnie to stwierdzić. Twoja metoda może być najszybsza, ale twoje pytanie jest wtedy zbyt zlokalizowane. - SilentGhost


Lub, jeśli chcesz korzystać z biblioteki zewnętrznej (i macierzy o stałej długości), użyj numpy, który ma "+ =" i powiązane operacje dla operacji na miejscu.

import numpy as np
a = np.array([0, 1, 2])
b = np.array([3, 4, 5])
a += b

6
2018-05-10 11:21





[a [x] + b [x] dla x w zakresie (0, len (a))]


3
2018-05-10 11:11



właśnie to robi OP. - SilentGhost
To jest mniej typująca wersja, proszę konstruktywnie w swoim krytyce. Twój niewidomy krytyk nikomu nie pomaga. - ismail
nie jest to ani standardowe, ani wydajne. czy to wystarczająco konstruktywne dla ciebie? - SilentGhost
Chłód. Zrób coś w rodzaju pomiaru wydajności i porównaj lub zacytuj odniesienia. - S.Lott
o 30% wolniej w porównaniu do wersji Nadii na moim komputerze. - SilentGhost


Jeśli jesteś zwięzły, spróbuj ...

vectors = [[0.0, 1.0, 2.0],[3.0, 4.0, 5.0]]
[sum(col) for col in zip(*vectors)]

Chociaż nie mogę mówić za to.


1
2018-06-05 20:52





W ogólnym przypadku posiadania listy list można zrobić coś takiego:

In [2]: import numpy as np

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

In [4]: [sum(a[:,i]) for i in xrange(len(a[0]))]
Out[4]: [10, 11, 12]

1
2017-09-02 16:41





Można utworzyć funkcję, która pobiera rozmiar tablicy, wykonuje pętle i tworzy zwracaną tablicę, która zwraca.


0
2018-05-10 11:07



Dzięki, ale to nie wydaje się bardzo skuteczne. - Johan Kotlinski
@kotlinski. Co? Rozmiar tablicy to len (tablica), która nie jest "obliczeniem", ale atrybutem listy. Pętla jest z pewnością mniej typowana niż [0] + = b [0] ... a [999] + = b [999]. Również mniej podatne na błędy. Również bardziej oczywiste. Porzucę trochę wydajności, aby zapobiec błędom w błędach. - S.Lott
Myślę, że moim głównym zarzutem byłoby stworzenie i zwrócenie listy, która nie byłaby konieczna w tym przypadku. W przeciwnym razie, tak, nie jest gorszy od drugiego pomysłu. - Johan Kotlinski
Powiedziałem tylko, że zwracam tablicę / listę, ponieważ myślałem, że tego chcesz. - Ólafur Waage
", aby uzyskać wynik a = [3,0, 5,0, 7,0]." - Ólafur Waage


Poprawa (mniejsze zużycie pamięci) listy zrozumiałej

zaimportuj itertools a = [x + y dla x, y w itertools.izip (a, b)]

Właściwie, jeśli nie jesteś pewien, że coś zostanie zużyte, to chciałbym użyć wyrażenia generatora:

(x + y dla x, y w itertools.izip (a, b))


0
2018-05-10 17:43