7

Son zamanlarda 2 listelerinin çarpma istedik THIS soruya cevap bazı kullanıcı düzgün bir yol olduğunu düşünüyorum hangi madende yanında, numpy kullanarak aşağıdaki yolu önerdi Bunun gibi performans. herhangi bir şekilde başka bir yanıt listesi anlama kullanımını içeren bir çözüm:Niçin liste kavraması, çarpım dizileri için numpy'den çok daha hızlıdır? Ayrıca ben <code>aray.resize()</code> aynı vardır bulundu</p> <pre><code>(a.T*b).T </code></pre> <p>:

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") 

sonuç:

first: 1.49778485298 
second : 7.43547797203 

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

Ama kriter sonra liste anlama çok daha hızlı Numpy daha gerçekleştirir gördük

Görebildiğiniz gibi yaklaşık 5 kat daha hızlıdır. Liste anlama hala yanında comprehensions C gerçekleştirir listelemek bu noktanın 5 sefer faster.So oldu
a=np.array([[2,3,5],[3,6,2],[1,3,2]]) 
b=np.array([[4],[2],[1]]) 

a*b 

burada 2 iç içe döngü kullandı: ama en çok şaşırtan şey onun daha hızlı, devrik kullanmadan şu kodu olmasıydı ve bir zip işlevi Yani neden ne olabilir? Numpy içinde * operasyon nedeniyle mi?

Ayrıca timeit ile ilgili bir sorun olmadığını da unutmayınbölümünü setup ürününe ekledim.

Ben de fark yapmaz hala azaldıkça ama daha büyük Arras ile çalıştı duygusu:

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") 

sonucu: numpy Dizilerin

first: 10.7480301857 
second : 13.1278889179 
+2

.... Daha büyük diziler deneyin? – NightShadeQueen

+0

@NightShadeQueen Yine aynı sonucu denedim – Kasramvd

+0

@Kasramvd daha ne kadar denediniz? – Falmarri

cevap

12

Oluşturma yaratılması çok daha yavaştır listeler:

In [153]: %timeit a = [[2,3,5],[3,6,2],[1,3,2]] 
1000000 loops, best of 3: 308 ns per loop 

In [154]: %timeit a = np.array([[2,3,5],[3,6,2],[1,3,2]]) 
100000 loops, best of 3: 2.27 µs per loop 

Ayrıca, NumPy işlev çağrıları befor tarafından yapılan sabit maliyetler de olabilir. Hesaplamadaki et , hızlı bir C/Fortran fonksiyonu ile gerçekleştirilebilir. Bu, girişlerin NumPy dizileri,

olarak sağlanmasını içerebilir. Bu kurulum/sabit maliyetler, NumPy çözümlerinin, saf Python çözümlerinden doğal olarak daha hızlı olduğunu varsaymadan önce akılda tutulması gereken bir şeydir. Eğer kez büyük diziler kurmak ve daha sonra birçok hızlı NumPy işlemleri diziler üzerinde gerçekleştirdiğinizde NumPy parlar. Diziler küçük ise saf Python'dan daha iyi performans gösteremeyebilir çünkü kurulum maliyeti hesaplamaların hesaplanmış C/Fortran fonksiyonlarına yüklenmesinin yararından ağır basabilir. Küçük diziler için buna değer kılmak için yeterli hesaplamaları olmayabilir.


Eğer diziler boyutunu biraz artırmak ve kurulum içine diziler oluşturulmasını taşırsanız, o zaman NumPy saf Python göre çok daha hızlı olabilir:

import numpy as np 
from timeit import timeit 

N, M = 300, 300 

a = np.random.randint(100, size=(N,M)) 
b = np.random.randint(100, size=(N,)) 

a2 = a.tolist() 
b2 = b.tolist() 

s1=""" 
[[m*n for n in second] for m, second in zip(b2,a2)] 
""" 

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

s3 = """ 
a*b[:,None] 
""" 

assert np.allclose([[m*n for n in second] for m, second in zip(b2,a2)], (a.T*b).T) 
assert np.allclose([[m*n for n in second] for m, second in zip(b2,a2)], a*b[:,None]) 

print 's1: {:.4f}'.format(
    timeit(stmt=s1, number=10**3, setup='from __main__ import a2,b2')) 
print 's2: {:.4f}'.format(
    timeit(stmt=s2, number=10**3, setup='from __main__ import a,b')) 
print 's3: {:.4f}'.format(
    timeit(stmt=s3, number=10**3, setup='from __main__ import a,b')) 

verim

s1: 4.6990 
s2: 0.1224 
s3: 0.1234 
+0

Yani, buradaki test, veri yapılarının oluşturulmasını içermekte idi ve bu kaldırılanla birlikte, "numpy" daha hızlı mı olacak? – TigerhawkT3

+0

Evet Bunun nedeni budur çünkü liste anlamasında numpy dizisi kullanıldığında bu uyuşuk yaklaşımı yavaşlatır! – Kasramvd

+0

% timeit python_expression'unu yapabileceğiniz yerde hangi kabuk/yorumlayıcı kullanıyorsunuz? –

İlgili konular