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
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.