2012-10-26 29 views
6

Tôi có một mảng đối tượng NumPy chứa nhiều danh sách các số chỉ số:Tại sao chức năng vectơ bị vón cục dường như được gọi là thêm thời gian?

>>> idxLsts = np.array([[1], [0, 2]], dtype=object) 

tôi định nghĩa một hàm vectorized để nối thêm một giá trị cho mỗi danh sách:

>>> idx = 99 
>>> f = np.vectorize(lambda idxLst: idxLst.append(idx)) 

Tôi gọi hàm. Tôi không quan tâm đến giá trị trả về, chỉ là tác dụng phụ.

>>> f(idxLsts) 
array([None, None], dtype=object) 

Chỉ số 99 đã được thêm hai lần vào danh sách đầu tiên. Tại sao? Tôi bối rối.

>>> idxLsts 
array([[1, 99, 99], [0, 2, 99]], dtype=object) 

Với các giá trị khác của idxLsts, nó không xảy ra:

>>> idxLsts = np.array([[1, 2], [0, 2, 4]], dtype=object) 
>>> f(idxLsts) 
array([None, None], dtype=object) 
>>> idxLsts 
array([[1, 2, 99], [0, 2, 4, 99]], dtype=object) 

nghi ngờ của tôi là nó liên quan đến các tài liệu mà nói: "Xác định một hàm vectorized mà phải mất một lồng nhau Chức năng vectorized đánh giá pyfunc trên các bộ dữ liệu liên tiếp của các mảng đầu vào như hàm bản đồ python, ngoại trừ nó sử dụng các quy tắc phát sóng của numpy. "

Trả lời

7

Từ vectorize docstring:

The data type of the output of `vectorized` is determined by calling 
the function with the first element of the input. This can be avoided 
by specifying the `otypes` argument. 

Và từ mã:

 theout = self.thefunc(*newargs) 

Đây là một cuộc gọi thêm để thefunc, được sử dụng để xác định loại đầu ra. Đây là lý do tại sao yếu tố đầu tiên nhận được thêm hai số 99 s.

Hành vi này xảy ra trong trường hợp thứ hai của bạn cũng như:

import numpy as np 
idxLsts = np.array([[1, 2], [0,2,4]], dtype = object) 
idx = 99 
f = np.vectorize(lambda x: x.append(idx)) 
f(idxLsts) 
print(idxLsts) 

mang

[[1, 2, 99, 99] [0, 2, 4, 99]] 

Bạn có thể sử dụng np.frompyfunc thay vì np.vectorize:

import numpy as np 
idxLsts = np.array([[1, 2], [0,2,4]], dtype = object) 
idx = 99 
f = np.frompyfunc(lambda x: x.append(idx), 1, 1) 
f(idxLsts) 
print(idxLsts) 

mang

[[1, 2, 99] [0, 2, 4, 99]] 
+0

Một chú thích nhỏ: Tôi đã phát hiện ra rằng mặc dù các tài liệu nói rằng hành vi này "có thể tránh được bằng cách xác định 'tranh luận otypes'," cung cấp' otypes' không ngăn cản hai cuộc gọi (ít nhất trong phiên bản 1.6.2). – senderle

+1

@senderle: Cảm ơn. Tôi cũng không thể tránh cuộc gọi hai lần, ngoại trừ việc chỉ định 'otypes = '?'', ** và ** 'f.nout = 1' ** và **' f.lastcallargs = 1', có vẻ như Một chút điên :) – unutbu

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