Как присвоить значения объектам в numpy-массиве с помощью векторизации - PullRequest
0 голосов
/ 26 апреля 2019

Я новичок в Python и написал этот код, чтобы создать двумерный массив объектов для имитации физической решетки.

    import numpy as np  

    class Site:
       def __init__(self, label, status):
          self.l = label
          self.s = status

     vSite = np.vectorize(Site(0,2), otypes=[object])
     init_array = np.arange(25).reshape((5,5))
     lattice = np.empty((5,5), dtype=object)
     lattice[:,:] = vSite(init_array)

, но у меня есть ошибки в выводе

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-0c0dfed8eab8> in <module>()
      9 init_array = np.arange(25).reshape((5,5))
     10 lattice = np.empty((5,5), dtype=object)
---> 11 lattice[:,:] = vSite(init_array)

~/.local/lib/python3.5/site-packages/numpy/lib/function_base.py in __call__(self, *args, **kwargs)
   2753             vargs.extend([kwargs[_n] for _n in names])
   2754 
-> 2755         return self._vectorize_call(func=func, args=vargs)
   2756 
   2757     def _get_ufunc_and_otypes(self, func, args):

~/.local/lib/python3.5/site-packages/numpy/lib/function_base.py in _vectorize_call(self, func, args)
   2823             res = func()
   2824         else:
-> 2825             ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
   2826 
   2827             # Convert args to object arrays first

~/.local/lib/python3.5/site-packages/numpy/lib/function_base.py in _get_ufunc_and_otypes(self, func, args)
   2770                 ufunc = self._ufunc
   2771             else:
-> 2772                 ufunc = self._ufunc = frompyfunc(func, len(args), nout)
   2773         else:
   2774             # Get number of outputs and output types by calling the function on

TypeError: function must be callable

Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 26 апреля 2019

Я обнаружил, что np.frompyfunc - лучший инструмент для создания массивов пользовательских классов. Использование np.vectorize также работает, так как вы указываете otypes, но frompyfunc уже возвращает объекты и является немного более прямым и быстрым.

In [667]: class Site: 
     ...:        def __init__(self, label, status): 
     ...:           self.l = label 
     ...:           self.s = status 
     ...:        def __repr__(self):   # to improve display
     ...:            return f'Site({self.l},{self.s})' 
     ...:                                                                            
In [668]: f = np.frompyfunc(Site, 2,1)                                               
In [669]: f(np.zeros((2,3),int), np.ones((2,3),int)*2)                               
Out[669]: 
array([[Site(0,2), Site(0,2), Site(0,2)],
       [Site(0,2), Site(0,2), Site(0,2)]], dtype=object)
In [670]: f(np.arange(3),np.array(['a','b','c']))                                    
Out[670]: array([Site(0,a), Site(1,b), Site(2,c)], dtype=object)

Я должен предупредить вас, что для доступа к этим Site объектам также потребуется использование frompyfunc. Массивы объектов не в полной мере используют вычислительную скорость numpy. numpy вычисления работают быстрее всего при работе с числами, а не с объектами.

0 голосов
/ 26 апреля 2019

Функция np.vectorize() должна принимать функцию в качестве первого аргумента, а не общую переменную.Затем вызываемая функция сможет вызываться для массива numpy для применения его к каждому элементу массива.

Если вы хотите инициализировать массив numpy 3D, вам следует использовать np.empty(dim)действуйте следующим образом:

a=np.empty((n,m,l), dtype=object)

Этот массив будет иметь n * m * l значений.
Затем вы можете выполнить итерацию по матрице с циклом, чтобы заполнить ее:

for i in np.ndindex(a.shape):
    a[i] = Site(1,1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...