Почему этот код не возвращает массив кортежей? - PullRequest
0 голосов
/ 08 марта 2020

При выполнении следующего кода:

f=lambda m,n: (m,n)
np.fromfunction(f,(6,6),dtype=int)

я получаю следующий вывод:

(array([[0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4, 4],
        [5, 5, 5, 5, 5, 5]]), array([[0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5],
        [0, 1, 2, 3, 4, 5]]))

Почему я не получаю массив / список кортежей?

Мое ожидание пришло от https://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfunction.html

numpy.fromfunction(function, shape, **kwargs)
Construct an array by executing a function over each coordinate.

The resulting array therefore has a value fn(x, y, z) at coordinate (x, y, z).

Моя функция f (n, m) возвращает (n, m).

f2=lambda m,n: m+10*n
np.fromfunction(f2,(6,6),dtype=int)

дает следующий вывод

array([[ 0, 10, 20, 30, 40, 50],
       [ 1, 11, 21, 31, 41, 51],
       [ 2, 12, 22, 32, 42, 52],
       [ 3, 13, 23, 33, 43, 53],
       [ 4, 14, 24, 34, 44, 54],
       [ 5, 15, 25, 35, 45, 55]])

1 Ответ

2 голосов
/ 08 марта 2020

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]]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...