Numpy - convert a list of objects to an array without a subclass of ndarray

For simplicity, I have defined a class that is not subclassed from ndarray (for many reasons I find it very complicated), but has a __array__() method that returns nd.array of this fixed form. Let me call this class Foo .

In my script, I also generate large lists of Foo instances, and I want to convert them to numpy arrays of arrays. I can easily do this using the map function:

 numpy.array(map(lambda x: numpy.array(x), [foo_1, ..., foo_n])) 

and it works great. I'm just wondering how I can get things simpler and more efficient, and get the following:

 numpy.array([foo_1, ..., foo_n]) 

(in fact, it returns a "return error without exception" ...). It seems that providing the __array__ method __array__ not enough to authorize the conversion of list arrays. Any idea?

+5
source share
2 answers

From numpy.array docs, the object you are passing must satisfy:

An array, any object that displays the interface of an array, an object, the __array__ method returns an array or any (nested) sequence.

In fact, you are passing a list of foo objects, so this list does not expose the array interface and does not have an array method. This leaves only whether it is an embedded sequence. To be a nested sequence, your foo objects should probably be iterable. They are? ( emulating python container types )

Not sure if this is 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 described. It prints the expected ndarray (no exceptions). Hope 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() 
+3
source

This will be a little more efficient and more concise, you don't need lambda with a map:

 numpy.array(map(numpy.array,[foo_1, ..., foo_n])) 
0
source

Source: https://habr.com/ru/post/1200885/


All Articles