Warum ist das Listenverständnis beim Multiplizieren von Arrays viel schneller als das von Numpy?

Kürzlich habe ich auf @ geantwortDIE Frage, die die Multiplikation von 2 Listen wollte, schlug einige Benutzer den folgenden Weg mit numpy, neben meinem, was ich für den richtigen Weg halte:

(a.T*b).T

Auch ich fand, dassaray.resize() hat die gleiche Leistung wie das. In jedem Fall schlug eine andere Antwort eine Lösung unter Verwendung des Listenverständnisses vor:

[[m*n for n in second] for m, second in zip(b,a)]

Aber nach dem Benchmark habe ich gesehen, dass das Listenverständnis sehr viel schneller ist als numpy:

from timeit import timeit

s1="""
a=[[2,3,5],[3,6,2],[1,3,2]]
b=[4,2,1]

[[m*n for n in second] for m, second in zip(b,a)]
"""
s2="""
a=np.array([[2,3,5],[3,6,2],[1,3,2]])
b=np.array([4,2,1])

(a.T*b).T
"""

print ' first: ' ,timeit(stmt=s1, number=1000000)
print 'second : ',timeit(stmt=s2, number=1000000,setup="import numpy as np")

Ergebnis:

 first:  1.49778485298
second :  7.43547797203

Wie Sie sehen können, ist numpy ungefähr 5 Mal schneller. aber das überraschendste war, dass es schneller ist, ohne transponieren zu müssen, und für folgenden Code:

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

a*b 

Das Listenverständnis war immer noch 5-mal schneller. Abgesehen davon, dass das Listenverständnis in C ausgeführt wird, haben wir hier 2 verschachtelte Schleifen und ein @ verwendezip function Also woran kann das liegen? Liegt es an der Operation* in Zahlen?

Beachten Sie auch, dass es kein Problem mit @ gitimeit hier habe ich das @ geputtimport Teil vonsetup.

Ich habe es auch mit größeren Arras versucht, der Unterschied wird geringer, macht aber immer noch keinen Sinn:

s1="""
a=[[2,3,5],[3,6,2],[1,3,2]]*10000
b=[4,2,1]*10000

[[m*n for n in second] for m, second in zip(b,a)]
"""
s2="""
a=np.array([[2,3,5],[3,6,2],[1,3,2]]*10000)
b=np.array([4,2,1]*10000)

(a.T*b).T

"""



print ' first: ' ,timeit(stmt=s1, number=1000)
print 'second : ',timeit(stmt=s2, number=1000,setup="import numpy as np")

Ergebnis:

 first:  10.7480301857
second :  13.1278889179

Antworten auf die Frage(2)

Ihre Antwort auf die Frage