Arrays 如何构建numpy对象数组(对象包含另一个数组)
在另一种语言中,我喜欢使用包含每个类对象的对象数组,并且通过对象数组可以非常高效地访问每个对象。我正试图用Python和numpy做同样的事情。每个对象都有许多不同类型的成员,包括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
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数组成员,然后只对其进行迭代。其余的只是引用数据,而不是循环的一部分。fastnumpy
代码适用于数字数据类型,而不是对象数据类型。在这种情况下,它可以在编译代码中进行迭代。但是对象数据类型数组保留对对象的引用,就像列表一样。执行一些基本计时;我认为,您将看到,在对象数据类型数组上的迭代要比列表迭代慢。我会选择numpy数组成员,并只对其进行迭代。其余的只是引用数据,而不是循环的一部分。好吧,我想它会回到列表中,但我需要先了解您在做什么。我可以问一个后续问题吗?如果更好的话,我很乐意提出一个新问题-如果我们还不知道需要调用哪个对象呢l、 但需要迭代所有对象以找到与我们的条件匹配的对象,例如:“给我intmember为5的对象”是否有一些有效的魔法可能?每个对象都必须被查询,就像一个列表一样。“有效的numpy魔法”是针对数字的,而不是一般的python对象。好吧,我想回到列表上来,但我需要先了解你在做什么。我可以问一个后续问题吗?如果更好的话,我很乐意提出一个新问题-如果我们还不知道需要拉哪一个对象,但需要迭代所有对象以找到与我们的条件匹配的对象,例如:“给我intmember为5的对象”是否可能有一些有效的魔法?每个对象都必须被查询,就像是一个列表一样。“有效的numpy魔法”用于数字,而不是一般的python对象。