2015-05-04 26 views
6

Potansiyel olarak aptalca bir şeyde kaybolacak gibi görünüyor. N boyutlu bir numpy dizilim var ve bir vektörle (1d dizisi) bir boyut boyunca çarpmak istiyorum (bu değişebilir!). Örnek olarak , ben böyle bir şey yapabileceği ilk dizinin ekseni 0 boyunca 1d dizisi ile 2d diziyi çarpmak istiyorum ki:Verilen bir eksen boyunca 1d dizili nump ndarray'ını çarpma

a=np.arange(20).reshape((5,4)) 
b=np.ones(5) 
c=a*b[:,np.newaxis] 

Kolay ama bu fikri iletmek istiyorum n-boyutları (a için, b her zaman 1d iken) ve herhangi bir eksene. Başka bir deyişle, np.newaxis ile doğru yerde bir dilim nasıl üretileceğini bilmek istiyorum.

c=a*b[np.newaxis,:,np.newaxis] 

yani: 3b olduğunu varsayalım ve eksen = 1 boyunca çarpma istiyorum, doğru bir şekilde verecek dilim oluşturmak istiyorum I çoğalmaya istediğiniz boyunca (örneğin 3) ve eksen boyutlarının sayısı göz önüne alındığında (örneğin eksen = 1), bir oluşturmak ve dilim geçmesi nasıl:

np.newaxis,:,np.newaxis 

teşekkür ederiz.

+0

Bunu gerçekleştirmeye çalıştığınız şey hakkında biraz daha bilgi verir misiniz? –

+0

Bir ndarray ile ilgili verilerim var ve verileri bir eksen boyunca bir filtre ile çarpmak istiyorum. –

cevap

6

Çözüm Kodu - adımların bir demo için

import numpy as np 

# Given axis along which elementwise multiplication with broadcasting 
# is to be performed 
given_axis = 1 

# Create an array which would be used to reshape 1D array, b to have 
# singleton dimensions except for the given axis where we would put -1 
# signifying to use the entire length of elements along that axis 
dim_array = np.ones((1,a.ndim),int).ravel() 
dim_array[given_axis] = -1 

# Reshape b with dim_array and perform elementwise multiplication with 
# broadcasting along the singleton dimensions for the final output 
b_reshaped = b.reshape(dim_array) 
mult_out = a*b_reshaped 

Numune koşmak - Şimdi

In [149]: import numpy as np 

In [150]: a = np.random.randint(0,9,(4,2,3)) 

In [151]: b = np.random.randint(0,9,(2,1)).ravel() 

In [152]: whos 
Variable Type  Data/Info 
------------------------------- 
a   ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
b   ndarray 2: 2 elems, type `int32`, 8 bytes 

In [153]: given_axis = 1 

, biz given axis = 1 boyunca elementwise şu işlemleri yapar istiyorum. b & elementwise çarpma işlemini yeniden şekillendirmek, Nihayet

In [154]: dim_array = np.ones((1,a.ndim),int).ravel() 
    ...: dim_array[given_axis] = -1 
    ...: 

In [155]: dim_array 
Out[155]: array([ 1, -1, 1]) 

: en dim_array yaratalım tekrar

In [156]: b_reshaped = b.reshape(dim_array) 
    ...: mult_out = a*b_reshaped 
    ...: 

Kontrol dışarı whos info ve b_reshaped & mult_out özel dikkat:

In [157]: whos 
Variable  Type  Data/Info 
--------------------------------- 
a   ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
b   ndarray 2: 2 elems, type `int32`, 8 bytes 
b_reshaped ndarray 1x2x1: 2 elems, type `int32`, 8 bytes 
dim_array ndarray 3: 3 elems, type `int32`, 12 bytes 
given_axis int  1 
mult_out  ndarray 4x2x3: 24 elems, type `int32`, 96 bytes 
+0

Tamam, benim hatamdan bahsetmedim: Uygun bir boyutta eşleştirme ile bir kopya oluşturamıyorum a, çünkü çok büyük olabilir. –

+0

Hey, hayır, üzgünüm, aslında bir çözüm, onu yanlış anlamıştım. Çok teşekkürler! –

+0

@AJC Gerçekten sorun yok! Önceki yorumumu kaldırıyorum. – Divakar

2

B yapabilirsin Bir dilim nesnesini uildikten sonra istediğiniz boyutu seçin:

import numpy as np 

a = np.arange(18).reshape((3,2,3)) 
b = np.array([1,3]) 

ss = [None for i in range(a.ndim)] 
ss[1] = slice(None) # set the dimension along which to broadcast 

print ss # [None, slice(None, None, None), None] 

c = a*b[ss]