Arrays 如何构建numpy对象数组(对象包含另一个数组)

Arrays 如何构建numpy对象数组(对象包含另一个数组),arrays,numpy,oop,Arrays,Numpy,Oop,在另一种语言中,我喜欢使用包含每个类对象的对象数组,并且通过对象数组可以非常高效地访问每个对象。我正试图用Python和numpy做同样的事情。每个对象都有许多不同类型的成员,包括numpy数组本身。因此,在最终结果中,我需要一个包含所有对象的对象数组,可以有效地访问并返回任何成员,最重要的是成员数组 我试过这样的方法: class TestClass(): objectarray=np.empty([10, 1], dtype=np.object) ## static array h

在另一种语言中,我喜欢使用包含每个类对象的对象数组,并且通过对象数组可以非常高效地访问每个对象。我正试图用Python和numpy做同样的事情。每个对象都有许多不同类型的成员,包括numpy数组本身。因此,在最终结果中,我需要一个包含所有对象的对象数组,可以有效地访问并返回任何成员,最重要的是成员数组

我试过这样的方法:

class TestClass():
    objectarray=np.empty([10, 1], dtype=np.object)  ## static array holding all class objects
    def __init__(self,name,position):
        self.name=name
        self.position=position
        self.intmember= 5
        self.floatmember=3.4
        self.arraymember= np.zeros([5, 5])  ## another array which is a member of the class
        TestClass.objectarray[position]=self
然后:

好像发生了什么事

TestClass.objectarray

array([[None],
       [None],
       [None],
       [None],
       [None],
       [<__main__.TestClass object at 0x000000EF214DC308>],
       [None],
       [None],
       [None],
       [None]], dtype=object)
TestClass.objectarray
数组([[None],
[无],,
[无],,
[无],,
[无],,
[],
[无],,
[无],,
[无],,
[无]],数据类型=对象)
但是,这不起作用:

a= TestClass.objectarray[5]
a.intmember
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-40-dac52811af13> in <module>
      1 a= TestClass.objectarray[5]
----> 2 a.intmember

AttributeError: 'numpy.ndarray' object has no attribute 'intmember'
a=TestClass.objectarray[5]
a、 内部成员
---------------------------------------------------------------------------
AttributeError回溯(最近一次呼叫上次)
在里面
1A=TestClass.objectarray[5]
---->2 a.成员
AttributeError:'numpy.ndarray'对象没有属性'intmember'
我做错了什么?请记住,这需要是一个大循环中的有效机制

(PS(我知道我可以使用对象列表,但在测试中迭代列表的速度太慢了。因此我想使用numpy数组,最好是由numba扩展)

根据定义,
testobj1
具有
intmember
属性:

In [3]: testobj1                                                                               
Out[3]: <__main__.TestClass at 0x7fceba8acef0>
In [4]: testobj1.intmember                                                                     
Out[4]: 5
我不认为创建(10,1)数组有帮助;简单的1d也一样好:

 objectarray=np.empty([10], dtype=np.object) 
或者只是一个列表:

In [12]: class TestClass(): 
    ...:     objectarray=[None]*10 
    ...:     def __init__(self,name,position): 
    ...:         self.name=name 
    ...:         self.position=position 
    ...:         self.intmember= 5 
    ...:         self.floatmember=3.4 
    ...:         self.arraymember= np.zeros([5, 5])  ## another array which is a member of the 
    ...: class 
    ...:         TestClass.objectarray[position]=self 
    ...:                                                                                       
In [13]: testobj1 = TestClass('test1',5)                                                       
In [14]: testobj1                                                                              
Out[14]: <__main__.TestClass at 0x7fceac25f5c0>
In [15]: testobj1.objectarray                                                                  
Out[15]: 
[None,
 None,
 None,
 None,
 None,
 <__main__.TestClass at 0x7fceac25f5c0>,
 None,
 None,
 None,
 None]
In [16]: testobj1.objectarray[5]                                                               
Out[16]: <__main__.TestClass at 0x7fceac25f5c0>
In [17]: testobj1.objectarray[5].intmember                                                     
Out[17]: 5
frompyfunc 我推荐
np.frompyfunc
作为访问或处理对象数据类型数组的方便(如果不是很快的话)方法

获取
intmember
值(如果存在)的函数:

In [28]: def getval(item): 
    ...:     try: 
    ...:         return item.intmember 
    ...:     except AttributeError: 
    ...:         return None         
应用于对象数组:

In [18]: timeit Out[5][5,0].intmember                                                          
149 ns ± 0.00964 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [19]: timeit Out[15][5].intmember                                                           
90.5 ns ± 0.0478 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [29]: np.frompyfunc(getval,1,1)(Out[5])                                                     
Out[29]: 
array([[None],
       [None],
       [None],
       [None],
       [None],
       [5],
       [None],
       [None],
       [None],
       [None]], dtype=object)
适用于列表:

In [30]: np.frompyfunc(getval,1,1)(Out[15])                                                    
Out[30]: 
array([None, None, None, None, None, 5, None, None, None, None],
      dtype=object)
时间:

In [31]: timeit np.frompyfunc(getval,1,1)(Out[15])                                             
14.6 µs ± 187 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [32]: timeit np.frompyfunc(getval,1,1)(Out[5])                                              
9.53 µs ± 54 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [33]: [getval(i) for i in Out[15]]                                                          
Out[33]: [None, None, None, None, None, 5, None, None, None, None]
In [34]: timeit [getval(i) for i in Out[15]]                                                   
6.53 µs ± 93.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
列表上的列表理解速度最快

根据定义,
testobj1
具有
intmember
属性:

In [3]: testobj1                                                                               
Out[3]: <__main__.TestClass at 0x7fceba8acef0>
In [4]: testobj1.intmember                                                                     
Out[4]: 5
我不认为创建(10,1)数组有帮助;简单的1d也一样好:

 objectarray=np.empty([10], dtype=np.object) 
或者只是一个列表:

In [12]: class TestClass(): 
    ...:     objectarray=[None]*10 
    ...:     def __init__(self,name,position): 
    ...:         self.name=name 
    ...:         self.position=position 
    ...:         self.intmember= 5 
    ...:         self.floatmember=3.4 
    ...:         self.arraymember= np.zeros([5, 5])  ## another array which is a member of the 
    ...: class 
    ...:         TestClass.objectarray[position]=self 
    ...:                                                                                       
In [13]: testobj1 = TestClass('test1',5)                                                       
In [14]: testobj1                                                                              
Out[14]: <__main__.TestClass at 0x7fceac25f5c0>
In [15]: testobj1.objectarray                                                                  
Out[15]: 
[None,
 None,
 None,
 None,
 None,
 <__main__.TestClass at 0x7fceac25f5c0>,
 None,
 None,
 None,
 None]
In [16]: testobj1.objectarray[5]                                                               
Out[16]: <__main__.TestClass at 0x7fceac25f5c0>
In [17]: testobj1.objectarray[5].intmember                                                     
Out[17]: 5
frompyfunc 我推荐
np.frompyfunc
作为访问或处理对象数据类型数组的方便(如果不是很快的话)方法

获取
intmember
值(如果存在)的函数:

In [28]: def getval(item): 
    ...:     try: 
    ...:         return item.intmember 
    ...:     except AttributeError: 
    ...:         return None         
应用于对象数组:

In [18]: timeit Out[5][5,0].intmember                                                          
149 ns ± 0.00964 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [19]: timeit Out[15][5].intmember                                                           
90.5 ns ± 0.0478 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [29]: np.frompyfunc(getval,1,1)(Out[5])                                                     
Out[29]: 
array([[None],
       [None],
       [None],
       [None],
       [None],
       [5],
       [None],
       [None],
       [None],
       [None]], dtype=object)
适用于列表:

In [30]: np.frompyfunc(getval,1,1)(Out[15])                                                    
Out[30]: 
array([None, None, None, None, None, 5, None, None, None, None],
      dtype=object)
时间:

In [31]: timeit np.frompyfunc(getval,1,1)(Out[15])                                             
14.6 µs ± 187 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [32]: timeit np.frompyfunc(getval,1,1)(Out[5])                                              
9.53 µs ± 54 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [33]: [getval(i) for i in Out[15]]                                                          
Out[33]: [None, None, None, None, None, 5, None, None, None, None]
In [34]: timeit [getval(i) for i in Out[15]]                                                   
6.53 µs ± 93.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

列表中的列表理解速度最快。

fast
numpy
代码适用于数字数据类型,而不是对象数据类型。在这种情况下,它可以在编译代码中迭代。但是对象数据类型数组保存对对象的引用,就像列表一样。做一些基本的计时;我认为,您会看到,在对象数据类型数组上的迭代速度较慢(而不是列表迭代)。我会选择numpy数组成员,然后只对其进行迭代。其余的只是引用数据,而不是循环的一部分。fast
numpy
代码适用于数字数据类型,而不是对象数据类型。在这种情况下,它可以在编译代码中进行迭代。但是对象数据类型数组保留对对象的引用,就像列表一样。执行一些基本计时;我认为,您将看到,在对象数据类型数组上的迭代要比列表迭代慢。我会选择numpy数组成员,并只对其进行迭代。其余的只是引用数据,而不是循环的一部分。好吧,我想它会回到列表中,但我需要先了解您在做什么。我可以问一个后续问题吗?如果更好的话,我很乐意提出一个新问题-如果我们还不知道需要调用哪个对象呢l、 但需要迭代所有对象以找到与我们的条件匹配的对象,例如:“给我intmember为5的对象”是否有一些有效的魔法可能?每个对象都必须被查询,就像一个列表一样。“有效的numpy魔法”是针对数字的,而不是一般的python对象。好吧,我想回到列表上来,但我需要先了解你在做什么。我可以问一个后续问题吗?如果更好的话,我很乐意提出一个新问题-如果我们还不知道需要拉哪一个对象,但需要迭代所有对象以找到与我们的条件匹配的对象,例如:“给我intmember为5的对象”是否可能有一些有效的魔法?每个对象都必须被查询,就像是一个列表一样。“有效的numpy魔法”用于数字,而不是一般的python对象。