Numpy迭代2d对象数组

时间:2018-04-12 06:52:41

标签: python arrays numpy

我有一个2D对象数组。我想迭代这个数组,并打印每个对象的一些属性。以下是我的代码:

import numpy as np
class example:
def __init__(self):
    self.number = 1
a = example()
b = example()
c = example()
d = example()
array = np.array([[a,b],[c,d]],dtype=np.object)
for x in np.nditer(array,["refs_ok"]):
     print x

错误讯息:AttributeError: 'numpy.ndarray' object has no attribute 'number'

我怎样才能实现目标?谢谢!

1 个答案:

答案 0 :(得分:0)

In [81]: class example:
    ...:     def __init__(self):
    ...:         self.number = 1
    ...:         
In [82]: a = example()
In [83]: b = example()

对于样本 1d 数组,简单迭代就足够了:

In [84]: arr = np.array([a,b], object)
In [85]: arr
Out[85]: 
array([<__main__.example object at 0xaa7d530c>,
       <__main__.example object at 0xaa5f84ec>], dtype=object)
In [86]: for a in arr:
    ...:     print(a.number)
    ...:     
1
1

我不鼓励使用nditer,除非你确实需要它,或打算最终在编译代码中使用它。它不是一种更快的迭代方式(在Python级别)。但如果你使用它,你需要了解它的作用:

In [89]: for x in np.nditer(arr,["refs_ok"]):
    ...:     print(x, type(x), x.shape)
    ...:     
    ...:     
<__main__.example object at 0xaa7d530c> <class 'numpy.ndarray'> ()
<__main__.example object at 0xaa5f84ec> <class 'numpy.ndarray'> ()

x是一个包含该对象的0d数组。它不是对象本身。要访问object属性,需要从数组中提取对象:

In [90]: for x in np.nditer(arr,["refs_ok"]):
    ...:     print(x.item(), x.item().number)
    ...:     
    ...:     
<__main__.example object at 0xaa7d530c> 1
<__main__.example object at 0xaa5f84ec> 1

nd对象数组

对于2d,我们可以进行双循环,或者展平数组然后循环。但frompyfunc可以很好地将函数应用于数组的每个元素。它是np.vectorize的基础函数(也可以使用它。

In [91]: arr = np.array([[a,b],[b,a]],dtype=np.object)
In [92]: arr
Out[92]: 
array([[<__main__.example object at 0xaa5f84ec>,
        <__main__.example object at 0xaa5f84ec>],
       [<__main__.example object at 0xaa5f84ec>,
        <__main__.example object at 0xaa5f84ec>]], dtype=object)
In [93]: f = np.frompyfunc(lambda x: x.number, 1, 1)
In [94]: f(arr)
Out[94]: 
array([[1, 1],
       [1, 1]], dtype=object)

nditer也适用于2D阵列:

In [95]: for x in np.nditer(arr,["refs_ok"]):
    ...:     print(x.item(), x.item().number)
    ...: 
<__main__.example object at 0xaa5f84ec> 1
<__main__.example object at 0xaa5f84ec> 1
<__main__.example object at 0xaa5f84ec> 1
<__main__.example object at 0xaa5f84ec> 1

或从https://docs.scipy.org/doc/numpy-1.13.0/reference/arrays.nditer.html#iterator-allocated-output-arrays复制:

In [97]: it =  np.nditer([arr,None],["refs_ok"],)
    ...: for x,y in it:
    ...:     y[...] = x.item().number
    ...:     
    ...: 
In [98]: it.operands
Out[98]: 
(array([[<__main__.example object at 0xaa5f84ec>,
         <__main__.example object at 0xaa5f84ec>],
        [<__main__.example object at 0xaa5f84ec>,
         <__main__.example object at 0xaa5f84ec>]], dtype=object),
 array([[1, 1],
        [1, 1]], dtype=object))