简体   繁体   中英

numpy - transform a list of objects into an array without subclassing ndarray

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()

这将更高效,更简洁,您不需要带有map的lambda

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

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