2013-04-04 3 views
2

Я пытаюсь создать массив NumPy, заполненный объектом, и мне было интересно, есть ли способ, которым я мог бы транслировать весь массив для каждого объекта, чтобы что-то сделать.Вызов функции широковещания в np.array

Код:

class player: 
    def __init__(self,num = 5): 
     self.num = num 

    def printnum(): 
     print(self.num) 
... 

objs = np.array([player(5),player(6)],dtype=Object) 
objs.printnum() 

Как она стоит это возвращает ошибку. Я попытался изменить dtype на: _объект согласно руководству, но ничего не работает.

ответ

0

Множество объектов с множеством объектов не наследует методы этого объекта. ndarray методы в целом действуют на весь массив

Это не работает для встроенных типов либо, например:

In [122]: import numpy as np 

In [123]: n = 4.0 

In [124]: a = np.arange(n) 

In [125]: n.is_integer() 
Out[125]: True 

In [126]: a.is_integer() 
--------------------------------------------------------------------------- 
AttributeError: 'numpy.ndarray' object has no attribute 'is_integer' 

Numpy вещание осуществляется с поэлементно операторами, например, дополнение:

In [127]: n 
Out[127]: 4.0 

In [128]: a 
Out[128]: array([ 0., 1., 2., 3.]) 

In [129]: n + a 
Out[129]: array([ 4., 5., 6., 7.]) 

Если вы хотите в основном вызвать print на все элементы вашего массива, вы можете просто переопределить метод .__repr__(), который вызывается print. Я бы предупредил вас, что вы потеряете информацию, переопределив метод.

In [148]: class player: 
    .....:  def __init__(self, num=5): 
    .....:   self.num = num 
    .....:  def __repr__(self): 
    .....:   return str(self.num) 
    .....:  

In [149]: objs = np.array([player(5), player(6)]) 

In [150]: objs 
Out[150]: array([5, 6], dtype=object) 

In [151]: print objs 
[5 6] 

Даже если это выглядит как это, это не то же самое, как np.array([5,6]) хотя:

In [152]: objs * 3 
---------------------- 
TypeError: unsupported operand type(s) for *: 'instance' and 'int' 

И вы можете увидеть недостаток перекрывая __repr__.

Чем проще способ сделать это, чтобы использовать текущий printnum() метод, но назвать его в цикле:

In [164]: class player: 
    .....:  def __init__(self, num=5): 
    .....:   self.num = num 
    .....:  def printnum(self): 
    .....:   print(self.num) 
    .....:   

In [165]: for p in objs: 
    .....:  p.printnum() 
    .....: 
5 
6 

Или, возможно, определить ваш метод возвращает строку, а не печатать один, то сделать лист понимание:

In [169]: class player: 
    .....:  def __init__(self, num=5): 
    .....:   self.num = num 
    .....:  def printnum(self): 
    .....:   return str(self.num) 
    .....: 

In [170]: objs = np.array([player(5), player(6)]) 

In [171]: [p.printnum() for p in objs] 
Out[171]: ['5', '6'] 
+0

я вижу. Я старался изо всех сил избегать использования цикла for. Спасибо, это отвечает на мой вопрос. – user2243024

+0

FYI, @ user2243024 типы «элементарных» функций (я использовал '+' как мой пример), которые передаются по массиву, называются ['ufunc'] (http://docs.scipy.org/doc/ NumPy/ссылка/ufuncs.html) – askewchan

0

пару опечаток в вашем коде: printnum() необходим self ARG, и Object ->object

class player: 
    def __init__(self, num=5): 
     self.num = num 

    def printnum(self): 
     print(self.num) 


objs = np.array([player(5),player(6)], dtype=object) 

# It's not a "broadcast" (what you mean is map), but it has the same result 
# plus it's pythonic (explicit + readable) 
for o in objs: 
    o.printnum() 

Похоже, что вы действительно хотите сделать, это создать объект генератора. Google python generator yield, и вы получите несколько примеров, таких как this

Смежные вопросы