2016-06-07 24 views
5

Giả sử tôi có 2 mảng sau:Sum chênh lệch bình phương giữa 2 NumPy mảng

import numpy as np 
a=np.asarray([[1,2,4], 
     [3,1,2]]) 
b=np.asarray([[2,1,1], 
     [3,2,3], 
     [4,1,2], 
     [2,2,1],]) 

Đối với mỗi a_row hàng trong một, tôi muốn có được số tiền chênh lệch bình phương giữa a_row và mỗi dòng trong b . Mảng kết quả sẽ là một mảng từ 2 đến 4. Kết quả dự kiến ​​sẽ được như sau:

array([[ 11., 5., 14., 10.], 
     [ 2., 2., 1., 3.]]) 

Tôi đã thực hiện một giải pháp sử dụng vòng lặp:

c=np.zeros((2,4)) 
for e in range(a.shape[0]): 
    c[e,:] = np.sum(np.square(b-a[e,:]),axis=1) 
print c 

Những gì tôi cần là một giải pháp hoàn toàn vectorized, tức là không có vòng lặp là bắt buộc.

+0

Có vẻ như một cách tự nhiên cho lambdas và đóng cửa. – duffymo

Trả lời

3

Đây là một cách tiếp cận Numpythonic, đơn giản bằng cách định hình lại các b để có thể trực tiếp trừ đi a từ nó:

>>> np.square(b[:,None] - a).sum(axis=2).T 
array([[11, 5, 14, 10], 
     [ 2, 2, 1, 3]]) 
+0

Xin chào Kasravand, cảm ơn câu trả lời của bạn. Nó hoạt động với mảng mẫu nhưng tôi gặp lỗi bộ nhớ trong các tập lệnh thực tế của mình. Trong kịch bản của tôi, hình dạng của mảng là (500,3072) và hình dạng của b là (5000,3072). Tôi đoán có lẽ vì phương pháp này là bộ nhớ chuyên sâu? Tôi đã không nhận được lỗi bằng cách sử dụng phương pháp vòng lặp được đề cập trong câu hỏi của tôi. – Allen

+0

@Tất cả tôi đề xuất 2 cách, lúc đầu nếu bạn không giao dịch với số lượng lớn, bạn có thể chuyển đổi mảng [loại] của bạn (http://docs.scipy.org/doc/numpy-1.10.1/user/basics. types.html) vào một kiểu đơn giản hơn như 'int8', nếu không thể, bạn có thể chia mảng của mình thành các mảng ngắn hơn và thực hiện thao tác với chúng một cách riêng biệt, sau đó ghép nối kết quả. Đây là câu trả lời hay http://stackoverflow.com/questions/31268998/how-to-merge-two-large-numpy-arrays-if-slicing-doesnt-resolve-memory-error – Kasramvd

3

Nếu bạn có quyền truy cập vào scipy, sau đó bạn có thể làm:

import scipy 
from scipy.spatial.distance import cdist 

import numpy as np 

a=np.asarray([[1,2,4], 
     [3,1,2]]) 
b=np.asarray([[2,1,1], 
     [3,2,3], 
     [4,1,2], 
     [2,2,1],]) 

x = cdist(a,b)**2 
# print x 
# array([[ 11., 5., 14., 10.], 
#  [ 2., 2., 1., 3.]]) 

này sử dụng các chức năng cdist được vector hóa và nhanh chóng. Bạn có thể có thể nhận được một chút tốc độ hơn bằng cách sử dụng tê hoặc cython, nhưng nó phụ thuộc vào kích thước của mảng của bạn trong thực tế.

+0

Cảm ơn Josh. Tôi đã thử nghiệm và nó hoạt động tốt. Tuy nhiên, trong trường hợp này, tôi cần một giải pháp được vector hóa hoàn toàn. tức là không thể sử dụng chức năng Scipy. – Allen

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