简体   繁体   中英

Numpy Iterate over 2d object array

I've got a 2D array of object. I want to iterate over this array, and print some attribute of every object. Below is my code:

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

Error message: AttributeError: 'numpy.ndarray' object has no attribute 'number'

How could I achieve my goal? Thanks!!

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

For sample 1d array, simple iteration is enough:

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

I don't encourage the use of nditer unless you really need it, or intend to use it eventually in compiled code. It isn't a faster way of iteration (at the Python level). But if you use it you need to understand what it does:

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 is a 0d array, containing the object. It is not the object itself. To access the object attribute, you need to extract the object from the array:

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 object array

For 2d, we could do a double loop, or flatten the array and then loop. But frompyfunc does a nice job of applying a function to each element of an array. It's the underlying function for np.vectorize (which could also have been used.

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 would also work on the 2d array:

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

Or copying from 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))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM