For sake of simplicity I've defined a class that is not subclassed from ndarray
(for many reasons I find it very complicated), but has an __array__()
method that returns a nd.array of a given fixed shape. Let's call this class Foo
.
In my script I also generate large lists of Foo instances, and I want to convert them into numpy arrays of arrays. I can easily do it using a map function:
numpy.array(map(lambda x: numpy.array(x), [foo_1, ..., foo_n]))
and it works fine. I was just wondering how I can get things ever more simpler and efficient, and get the following to work:
numpy.array([foo_1, ..., foo_n])
(actually it returns an "error return without exception set"...). It seems that providing an __array__
method is not sufficient to authorize array conversion of lists. Any idea?
From the numpy.array docs, the object you pass in must satisfy:
An array, any object exposing the array interface, an object whose
__array__
method returns an array, or any (nested) sequence.
You're actually passing in a list
of foo objects, so this list doesn't expose the array interface and doesn't have an array
method. That leaves only whether it's a nested sequence. To be a nested sequence, your foo objects would likely need to be iterable. Are they? (emulating python's container types)
Not sure if this is any better, but you could probably do:
numpy.array([numpy.array(x) for x in [foo_1, ..., foo_n]])
Here is an example of Foo
, as you've described. It outputs the ndarray you'd expect (no exceptions). Hopefully you can use it as an example:
import numpy as np
class Foo(object):
def __init__(self):
self.arr = np.array([[1, 2, 3], [4, 5, 6], [7,8,9]], np.int32)
def __array__(self):
return self.arr
def __iter__(self):
for elem in self.arr:
yield elem
def __len__(self):
return len(self.arr)
def __getitem__(self, key):
return self.arr[key]
def main():
foos = [Foo() for i in range(10)]
print np.array(foos)
if __name__ == '__main__':
main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With