我正在寻找某种范式或实现来有效地处理多组耦合的N-dim数组(ndarray
s)。具体来说,我希望实现允许我切片整个对象的数组(例如someObjs = objects[100:200]
),或者那些对象的个别属性(例如somePars1 = objects.par1[100:200]
)---同时时间。
为了扩展上面的例子,我可以用两种方式构造以下子集:
def subset1(objects, beg, end):
pars1 = [ obj.par1 for obj in objects[beg:end] ]
pars2 = [ obj.par2 for obj in objects[beg:end] ]
return pars1, pars2
def subset2(objects, beg, end):
pars1 = objects.par1[beg:end]
pars2 = objects.par2[beg:end]
return pars1, pars2
他们会完全相同。
编辑:
一种方法是覆盖__getitem__
(等)方法,例如,
class Objects(object):
def __init__(self, p1, p2):
self.par1 = p1
self.par2 = p2
...
def __getitem__(self, key):
return Objects(self.p1[key], self.p2[key])
但这非常低效,并且它重复了子集。或许还有某种方法可以返回子集的view
答案 0 :(得分:2)
具有数组方法的对象数组和对象
示例对象类
In [56]: class MyObj(object):
....: def __init__(self, par1,par2):
....: self.par1=par1
....: self.par2=par2
这些对象的数组 - 仅仅是带有数组包装器的列表
In [57]: objects=np.array([MyObj(1,2),MyObj(3,4),MyObj(2,3),MyObj(10,11)])
In [58]: objects
Out[58]:
array([<__main__.MyObj object at 0xb31b196c>,
<__main__.MyObj object at 0xb31b116c>,
<__main__.MyObj object at 0xb31b13cc>,
<__main__.MyObj object at 0xb31b130c>], dtype=object)
`subset``选择类型:
In [59]: [obj.par1 for obj in objects[1:-1]]
Out[59]: [3, 2]
另一个可以包含这样一个数组的类。这比定义数组子类更简单:
In [60]: class MyObjs(object):
....: def __init__(self,anArray):
....: self.data=anArray
....: def par1(self):
....: return [obj.par1 for obj in self.data]
In [61]: Obs = MyObjs(objects)
In [62]: Obs.par1()
Out[62]: [1, 3, 2, 10]
subset2
选择类型:
In [63]: Obs.par1()[1:-1]
Out[63]: [3, 2]
目前par1
是一种方法,但可以创建一个属性,允许Obs.par1[1:-1]
语法。
如果par1
返回数组而不是列表,则索引会更强大。
如果MyObjs
有__getitem__
方法,则可以使用
Obs[1:-1]
可以通过各种方式定义该方法,但最简单的方法是应用索引&#39;切片&#39;到了&#39;数据&#39;:
def __getitem__(self, *args):
# not tested
return MyObjs(self.data.__getitem(*args))
我只关注语法,而不关注效率。通常,一般对象的numpy数组不是非常快或强大。这些数组基本上是指向对象的指针列表。
结构化数组和重新排列版本
另一种可能性是np.recarray
。另一张海报只询问他们的名字。它们本质上是结构化数组,其中字段可以作为属性进行访问。
使用结构化数组定义:
In [64]: dt = np.dtype([('par1', int), ('par2', int)])
In [66]: Obj1 = np.array([(1,2),(3,4),(2,3),(10,11)], dtype=dt)
In [67]: Obj1
Out[67]:
array([(1, 2), (3, 4), (2, 3), (10, 11)],
dtype=[('par1', '<i4'), ('par2', '<i4')])
In [68]: Obj1['par1'][1:-1]
Out[68]: array([3, 2])
In [69]: Obj1[1:-1]['par1']
Out[69]: array([3, 2])
或作为recarray
In [79]: Objrec=np.rec.fromrecords(Obj1,dtype=dt)
In [80]: Objrec.par1
Out[80]: array([ 1, 3, 2, 10])
In [81]: Objrec.par1[1:-1]
Out[81]: array([3, 2])
In [82]: Objrec[1:-1].par1
Out[82]: array([3, 2])