2015-05-04 20 views
6

Có vẻ như tôi đang bị lạc trong một thứ có thể ngớ ngẩn. Tôi có một mảng numpy n-chiều, và tôi muốn nhân nó với một vector (mảng 1d) dọc theo một số kích thước (có thể thay đổi!). Như một ví dụ, nói rằng tôi muốn nhân một mảng 2ngày bởi một mảng 1d dọc theo trục 0 của mảng đầu tiên, tôi có thể làm một cái gì đó như thế này:nhân ndarray numpy với mảng 1d dọc theo một trục nhất định

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

dễ dàng, nhưng tôi muốn mở rộng ý tưởng này để n-dimension (cho a, trong khi b luôn là 1d) và tới bất kỳ trục nào. Nói cách khác, tôi muốn biết làm thế nào để tạo ra một lát với np.newaxis ở đúng nơi. Giả sử rằng a là 3d và tôi muốn nhân dọc theo trục = 1, tôi muốn tạo ra slice sẽ cung cấp chính xác:

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

I.e. cho số lượng kích thước của một (nói 3) và trục mà tôi muốn nhân (nói trục = 1), làm cách nào để tạo và chuyển slice:

np.newaxis,:,np.newaxis 

Cảm ơn.

+0

Bạn có thể giải thích thêm một chút về những gì bạn đang cố gắng đạt được bằng cách này? –

+0

Tôi có dữ liệu trên một đĩa dữ liệu, và tôi muốn nhân dữ liệu với một bộ lọc dọc theo một số trục. –

Trả lời

6

Giải pháp Mã -

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 

mẫu chạy cho một bản demo của các bước -

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 

Bây giờ, chúng tôi muốn thực hiện phép nhân elementwise cùng given axis = 1. Hãy tạo dim_array:

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

Cuối cùng, định hình lại b & thực hiện các phép nhân elementwise:

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

Kiểm tra các thông tin whos một lần nữa và đặc biệt chú ý đến b_reshaped & mult_out:

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

Ok, lỗi của tôi tôi đã không đề cập đến điều này: Tôi không thể tạo bản sao của b với kích thước thích hợp phù hợp với a, vì có thể rất rất lớn. –

+0

Hey, không, xin lỗi, nó thực sự là một giải pháp, tôi đã hiểu lầm nó. Cảm ơn rất nhiều! –

+0

@AJC Thật là ok! Đang xóa nhận xét trước của tôi. – Divakar

2

Bạn có thể b uild một đối tượng slice, và chọn kích thước mong muốn trong đó:

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] 
Các vấn đề liên quan