2013-07-10 20 views
10

Numpy dizisi yayınında aşağıdaki alıştırmaları göz önünde bulundurun.Numpy, python: yayın sırasında dizilerin boyutlarını otomatik olarak genişlet

import numpy as np 
v = np.array([[1.0, 2.0]]).T # column array 

A2 = np.random.randn(2,10) # 2D array 
A3 = np.random.randn(2,10,10) # 3D 

v * A2 # works great 

# causes error: 
v * A3 # error 

Ben yayın için Numpy kurallarını biliyorum ve Matlab bsxfun işlevselliği ile tanıdık. Bir (2, N, N) dizisine bir (2,1) dizisini göndermeyi denemenin neden başarısız olduğunu ve (2,1) dizisini bundan önce bir (2,1,1) diziye yeniden eklemem gerektiğini anlıyorum. yayın geçer.

Soruma şudur: Python'u yayınlamaya çalışırken dizinin boyutlarını otomatik olarak doldurması için herhangi bir yol var mı?

aksi takdirde ben aptal ve mult_v_A = lambda v,A: v.reshape([v.size] + [1]*(A.ndim-1)) * A gibi saçma çirkin bir şey yapabileceğini --- o karşı yayınlanacak olacak çok boyutlu dizi (2,1) vektörü için açıkça çift istemiyoruz . "A" dizisi 2D veya 3D veya N-D olacaksa, zamanın önünde bilmiyorum. Matlab'ın bsxfun yayın işlevselliği, boyutları gerektiği gibi zımbalı bir şekilde pedler, bu yüzden Python'da yapabileceğim bir şey olduğunu umuyorum. Numpe yayıncılık, sol tarafta ek eksenler ekler.

+4

Görünümüm, bunun bir özellik değil, bir hata olmasıdır. Örneğin, 2’de 1 sütun vektörüne sahip olduğunuzu varsayalım ve daha sonra 2'ye 2’lik bir 'ndarray’ınız vardı. “V” şeklini yeniden şekillendirmek istiyor musunuz (2,1,1) veya şekil (1,2,1) 'dir? Boyutları sadece doldurursanız, kullanıcı için belirsiz olabilir. Açık bir yeniden biçimlendirmeyi zorlamak daha iyi bir genel prosedürdür ve kullanıcının sabit bir sözleşmesi varsa, otomatik olarak yeniden şekillendirmek için özel bir işlev yazması için kullanıcıya bırakır. Ama size bir kongre zorlayan küresel bir "numpy" boyut-padder yapmak için iyi değil. Kötüye kullanmak çok kolay olurdu. – ely

+0

-1 @EMS. Bu belirsizlik, tekil olmayan ilk boyutun yayında kullanılacağını belirterek kolayca çözülebilir. "Bu yol daha iyi" şeklindeki bu tutum, profesyonel programcılar ve uygulamalı matematikçiler tarafından kullanılan sistemler için tamamen uygunsuzdur - bu bir özellik değil, okunaksızlık ve zorunluluk açısından bir kusurdur. –

+0

-1 @ Ahmed Fasih. Her gün bilimsel uygulamalar için Python kodunu yazan bir uygulamalı matematik uzmanıyım ve önerilen tekil olmayan tekil boyutu her zaman benimseme önerisinin çok zayıf olacağını düşünüyorum. Bu konvansiyonu benimseyen bir fonksiyon yazmanız için, NumPy geliştiricilerin, bazı kullanıcılara (sizin gibi) fayda sağlayan ama diğer bazı kullanıcılar (benim gibi) için yararlı olmayacak bir kongre gibi bir kodlamayı endişelendirmekten çok daha iyi. – ely

cevap

9

Bu çirkin, ama bu çalışacaktır : bunu herhangi bir bağımsız değişkeni vermezseniz artık onların büyü yapmak için yayın kurallarına güvenebilirsiniz böylece

(v.T * A3.T).T 

, aktarılmasını, şekil tuple tersine çevirir. Son aktarım her şeyi doğru sıraya döndürür.

+1

Aslında, @ unutbu'nun 'np.swapaxes (v.T * np.swapaxes (A3,0, -1), 0, -1) 'olduğunu inceledikten sonra sahip olduğumdan daha az çirkin! Transpoze'nin tüm boyutları tersine çevirdiğini bilmek bu kadar çok şeyi daha da zorlaştırıyor. En azından kullanıcılar bu dönüşümleri görecekler ve umarım "Tamam, ben tamamım" boyutlarını sıralamak için küçük bir dokunaklık dokunuşuyla, burada devam eden yayınlar var. " Teşekkürler şefi. –

8

Paylaşılan eksenleri sağda ve broadcastable eksenleri solda böylece diziler düzenlemek eğer

Yani, o zaman hiçbir sorun ile yayın kullanabilirsiniz:

import numpy as np 
v = np.array([[1.0, 2.0]]) # shape (1, 2) 

A2 = np.random.randn(10,2) # shape (10, 2) 
A3 = np.random.randn(10,10,2) # shape (10, 10, 2) 

v * A2 # shape (10, 2) 

v * A3 # shape (10, 10, 2) 
+0

Bu en azından yarım yoldur. Benim uygulamada kurulan konvansiyon ne yazık ki 'v' gibi vektörler sütun dizileridir. Kodun (ve benim kullanıcılarım) satır dizileri beklemesini yeniden yapılandırmak istemediğimi farz edersem, yayın çarpma yapmak için boyutlarını değiştiren bir işlevin gerçekten A 've 'iç içe geçen yeniden biçimlendirme işleminden daha az zorlanmış olup olmadığını tartışıyorum. Orijinal mesajımda –

+0

Numpy'nin boyutları sola değil sağa ekleyen bir nedeni var mı? Keyifli görünüyor ama belki de hafıza ya da cebirle ilgili bazı önemli gerekçeler var mı? –

+0

Muhtemelen kendi (alt) soruma cevap veriyorum, çünkü bu, dizilerin izleyen boyutlarında ve sola doğru yayınlanmaya başladığından ve kurallar yerine getirildiği sürece boyutların gerektiği gibi eklendiğinden mi kaynaklanıyor? İlginç! –