fromfunction
документы могут сбивать с толку. Но если вы посмотрите на код, то увидите, что он просто генерирует indices
и передает их целом в вашу функцию:
In [345]: f = lambda m,n: (m,n)
In [346]: np.fromfunction(f, (3,3), dtype=int)
Out[346]:
(array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]]), array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]))
In [348]: m,n = np.indices((3,3))
In [349]: m,n
Out[349]:
(array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2]]), array([[0, 1, 2],
[0, 1, 2],
[0, 1, 2]]))
Есть функция, которая будет кормить кортежи ваша функция:
In [351]: np.frompyfunc(f,2,1)(m,n)
Out[351]:
array([[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (2, 1), (2, 2)]], dtype=object)
np.vectorize
делает что-то подобное, но для этого frompyfunc
проще и быстрее.
Понимание этого списка так же быстро:
In [352]: [(i,j) for i,j in zip(m.ravel(),n.ravel())]
Out[352]: [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
Ваша вторая функция:
In [414]: m,n = np.indices((3,3))
In [415]: m*10*n
Out[415]:
array([[ 0, 0, 0],
[ 0, 10, 20],
[ 0, 20, 40]])
Фактический код:
def fromfunction(function, shape, **kwargs):
dtype = kwargs.pop('dtype', float)
args = indices(shape, dtype=dtype)
return function(*args, **kwargs)
====
f2=lambda m,n: m+10*n
работает в np.fromfunction
и np.frompyfunc
.
In [417]: f2=lambda m,n: m+10*n
In [418]: np.fromfunction(f2, (3,3), dtype=int)
Out[418]:
array([[ 0, 10, 20],
[ 1, 11, 21],
[ 2, 12, 22]])
In [420]: np.frompyfunc(f2,2,1)(m,n)
Out[420]:
array([[0, 10, 20],
[1, 11, 21],
[2, 12, 22]], dtype=object)
===
Вот функция, которая будет возвращать трехмерный массив, эквивалентный вашим вложенным кортежам:
In [426]: f3 = lambda m,n: np.stack((m,n), axis=2)
In [427]: np.fromfunction(f3,(3,3),dtype=int)
Out[427]:
array([[[0, 0],
[0, 1],
[0, 2]],
[[1, 0],
[1, 1],
[1, 2]],
[[2, 0],
[2, 1],
[2, 2]]])
In [428]: f3(m,n)
Out[428]:
array([[[0, 0],
[0, 1],
[0, 2]],
[[1, 0],
[1, 1],
[1, 2]],
[[2, 0],
[2, 1],
[2, 2]]])