2014-12-22 25 views
6

Tôi đã mong đợi np.fromfunction(lambda i: 1, (4,), dtype=int) để trả về array([1, 1, 1, 1]), nhưng trả về số nguyên 1 thay thế. Ai đó có thể giải thích cho tôi tại sao numpy.fromfunction hoạt động theo cách đó? Dường như nó có liên quan đến định nghĩa của hàm ẩn danh (tức là, một tham số của hàm này có thực sự được sử dụng) hay không.Kết quả không mong đợi - kết quả không chính xác với chức năng liên tục

>>> import numpy as np 

>>> np.fromfunction(lambda i: i, (4,), dtype=int) 
array([0, 1, 2, 3]) 

>>> np.fromfunction(lambda i: 1, (4,), dtype=int) 
1 

>>> np.fromfunction(lambda i: 1 + i*0, (4,), dtype=int) 
array([1, 1, 1, 1]) 

EDIT: để làm rõ, mục tiêu cuối cùng của tôi không phải là tạo ra array([1, 1, 1, 1]) sử dụng phương pháp này. Thay vào đó, tôi đang thực hiện cuộc gọi của biểu mẫu

np.fromfunction(lambda i: **an expression that doesn't depend on i**, (n,)) 

Nói cách khác, tôi đang cố gắng khởi tạo mảng nhiều lần bằng cách liên tục thực hiện cuộc gọi đến một số chức năng. (Có một cuộc gọi đến np.random.random() trong hàm đó vì vậy tôi không thực hiện cuộc gọi không cần thiết.)

+0

Nếu biểu thức không phụ thuộc vào 'i', tôi nghi ngờ bạn có thể thay thế việc sử dụng' a = np.fromfunction (lambda i: ** một biểu thức không phụ thuộc vào i **, (n,)) 'với một cái gì đó như' a = ** một biểu thức không phụ thuộc vào i ** ', và trong biểu thức, sử dụng một cái gì đó như' np.ones (n) ',' np.arange (n) ', vv, để có biểu thức tạo một mảng có kích thước phù hợp. –

+0

@WarrenWeckesser Tôi không chắc tôi hiểu. Liệu phương thức của bạn có hoạt động ngay cả khi có một lệnh gọi 'np.random.random()' bên trong '** một biểu thức không phụ thuộc vào i **'? –

+0

Bạn có thể sử dụng đối số 'size' của' np.random.random'. Nếu biểu thức của bạn là, '4 * u ** 2 + 1' trong đó 'u' là ngẫu nhiên, bạn có thể viết' a = 4 * np.random.ngẫu nhiên (size = n) ** 2 + 1'. –

Trả lời

6

Nó không được giải thích trong tài liệu của đối số func trong fromfunction docstring rằng func được gọi là chỉ sau khi, với đối số mảng.

Trong ví dụ này

np.fromfunction(lambda i: i, (4,), dtype=int) 

anonymous function được gọi một lần, với lập luận i là mảng [0, 1, 2, 3]. Để xác minh điều này, bạn có thể làm:

In [10] from __future__ import print_function 

In [11]: np.fromfunction(lambda i: print("i = %r" % (i,)), (4,), dtype=int) 
i = array([0, 1, 2, 3]) 

Trong trường hợp này, nơi func lợi nhuận 1,

np.fromfunction(lambda i: 1, (4,), dtype=int) 

vì giá trị được trả về bởi các cuộc gọi duy nhất là 1, các mảng được tạo ra chỉ chứa 1 Không phải là lý do tại sao bạn muốn sử dụng fromfunction để tạo một mảng 1s thay vì, giả sử, np.ones, nhưng trong trường hợp bạn có điều gì đó phức tạp hơn trong tâm trí, đây là một cách bạn có thể làm điều đó, bằng cách sử dụng np.ones_like:

In [14]: np.fromfunction(lambda i: np.ones_like(i), (4,), dtype=int) 
Out[14]: array([1, 1, 1, 1]) 
+2

Điều này có vẻ khá không trực quan. Có chức năng nào mà OP có ý định làm không? – Rufflewind

+0

Cảm ơn - điều đó thực sự làm rõ hành vi của sự cố. –

6

@Warren Weckesser đã giải thích lý do tại sao điều này xảy ra (các tài liệu NumPy là một chút sai lệch ở đây và nơi nào làm cho nó rõ ràng rằng fromfunction đang mong đợi một vector). Nếu bạn muốn làm cho công việc lambda chức năng của bạn với fromfunction bạn có thể vectorize nó một cách rõ ràng:

In [1]: func = lambda i: 1 
In [1]: vfunc = np.vectorize(func) 
In [2]: np.fromfunction(vfunc, (4,), dtype=int) 
Out[2]: array([1, 1, 1, 1]) 

Nhưng đối với trường hợp sử dụng này, tôi muốn nghĩ

np.ones(4, dtype=int) 

(có lẽ lần một hằng số) sẽ là tốt hơn.

+0

Ah, điều đó rất hữu ích để biết. Cảm ơn! –

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