2011-08-21 32 views
15

Có chức năng numpy để phân chia mảng dọc theo trục với các phần tử từ mảng khác không? Ví dụ: giả sử tôi có một mảng a có hình dạng (l, m, n) và một mảng b có hình dạng (m,); Tôi đang tìm một cái gì đó tương đương với:phân chia theo chiều dọc theo trục

def divide_along_axis(a,b,axis=None): 
    if axis is None: 
     return a/b 
    c = a.copy() 
    for i, x in enumerate(c.swapaxes(0,axis)): 
     x /= b[i] 
    return c 

Ví dụ, điều này rất hữu ích khi bình thường hóa một loạt các vectơ:

>>> a = np.random.randn(4,3) 
array([[ 1.03116167, -0.60862215, -0.29191449], 
     [-1.27040355, 1.9943905 , 1.13515384], 
     [-0.47916874, 0.05495749, -0.58450632], 
     [ 2.08792161, -1.35591814, -0.9900364 ]]) 
>>> np.apply_along_axis(np.linalg.norm,1,a) 
array([ 1.23244853, 2.62299312, 0.75780647, 2.67919815]) 
>>> c = divide_along_axis(a,np.apply_along_axis(np.linalg.norm,1,a),0) 
>>> np.apply_along_axis(np.linalg.norm,1,c) 
array([ 1., 1., 1., 1.]) 

Trả lời

23

Đối với ví dụ cụ thể mà bạn đã đưa ra: chia một (l, m, n) mảng bằng (m,), bạn có thể sử dụng np .newaxis:

a = np.arange(1,61, dtype=float).reshape((3,4,5)) # Create a 3d array 
a.shape           # (3,4,5) 

b = np.array([1.0, 2.0, 3.0, 4.0])    # Create a 1-d array 
b.shape           # (4,) 

a/b            # Gives a ValueError 

a/b[:, np.newaxis]        # The result you want 

Bạn có thể đọc tất cả về quy tắc phát sóng here. Bạn cũng có thể sử dụng newaxis nhiều lần nếu cần. (ví dụ: để chia mảng hình dạng (3,4,5,6) theo mảng hình (3,5)).

Từ sự hiểu biết của tôi về tài liệu, sử dụng tính năng mới + phát thanh cũng tránh bất kỳ việc sao chép mảng không cần thiết nào.

Lập chỉ mục, newaxis vv được mô tả đầy đủ hơn here ngay bây giờ. (Tài liệu được sắp xếp lại kể từ khi câu trả lời này được đăng lần đầu).

0

Tôi nghĩ rằng bạn có thể nhận được hành vi này với hành vi phát sóng thường lệ NumPy của:

In [9]: a = np.array([[1., 2.], [3., 4.]]) 

In [10]: a/np.sum(a, axis=0) 
Out[10]: 
array([[ 0.25  , 0.33333333], 
     [ 0.75  , 0.66666667]]) 

Nếu tôi đã giải thích chính xác.

Nếu bạn muốn trục khác mà bạn có thể transpose tất cả mọi thứ:

> a = np.random.randn(4,3).transpose() 
> norms = np.apply_along_axis(np.linalg.norm,0,a) 
> c = a/norms 
> np.apply_along_axis(np.linalg.norm,0,c) 
array([ 1., 1., 1., 1.]) 
+0

không, bạn chưa có. phương thức đó không thành công, ví dụ với mảng 2-d mà tôi đưa ra làm ví dụ. khi nó quay ra, ví dụ tôi đưa cho bạn có thể làm c = a/np.apply_along_axis (np.linalg.norm, 1, a) [:, np.newaxis] nhưng tôi đang tìm một cái gì đó tổng quát hơn giống như hàm divide_along_axis() i định nghĩa trong câu hỏi. – user545424

+1

Làm thế nào để chuyển đổi (xem câu trả lời đã chỉnh sửa)? Hoặc bạn có thể định nghĩa 'divide_along_axis' bằng cách transposing đầu tiên, chia, sau đó transposing trở lại. – Owen

+1

Chỉ cần thêm trục mới vào mảng 1d của bạn. – tillsten

Các vấn đề liên quan