python – Numpy中的Namedtuple
我非常喜欢namedtuple集合的功能.具体来说,我喜欢它对二维空间中的点有多大用处.
In : from collections import namedtuple In : Point = namedtuple('Point',['x','y']) In : p = Point(1,2) In : p.x Out: 1 In : p.y Out: 2 我认为这比引用列表的第一个和第二个条目要清楚得多.我想知道是否有办法使它成为Point也是一个numpy数组.例如 In: p1 = Point(1,2) In: p2 = Point(3,4) In: (p1+p2).x Out: 4 和numpy类似的好功能.换句话说,我想我想让Point成为numpy的子类?我可以这样做吗?如何? 解决方法
像point_type这样的结构化数组不定义涉及多个字段的数学运算.
样本来自https://stackoverflow.com/a/33455682/901925 In [470]: point_type = [('x',float),('y',float)] In [471]: points = np.array([(1,2),(3,4),(5,6)],dtype=point_type) In [472]: points Out[472]: array([(1.0,2.0),(3.0,4.0),(5.0,6.0)],dtype=[('x','<f8'),'<f8')]) In [473]: points[0]+points[1] ... TypeError: unsupported operand type(s) for +: 'numpy.void' and 'numpy.void' 相反,我可以创建一个二维数组,然后将其视为point_type – 数据缓冲区布局将是相同的: In [479]: points = np.array([(1,float) In [480]: points Out[480]: array([[ 1.,2.],[ 3.,4.],[ 5.,6.]]) In [481]: points.view(point_type) Out[481]: array([[(1.0,2.0)],[(3.0,4.0)],[(5.0,6.0)]],'<f8')]) In [482]: points.view(point_type).view(np.recarray).x Out[482]: array([[ 1.],[ 3.],[ 5.]]) 我可以跨行进行数学运算,并继续将结果视为点: In [483]: (points[0]+points[1]).view(point_type).view(np.recarray) Out[483]: rec.array([(4.0,'<f8')]) In [484]: _.x Out[484]: array([ 4.]) In [485]: points.sum(0).view(point_type) Out[485]: array([(9.0,12.0)],'<f8')]) 或者,我可以从point_type开始,然后将其视为数学的2d,然后再查看它 pdt1=np.dtype((float,(2,))) In [502]: points Out[502]: array([(1.0,'<f8')]) In [503]: points.view(pdt1) Out[503]: array([[ 1.,6.]]) In [504]: points.view(pdt1).sum(0).view(point_type) Out[504]: array([(9.0,'<f8')]) 因此,可以以2d和重新排列的形式查看和操作数组.为了漂亮或有用,它可能需要在用户定义的类中埋葬. 从recarray类中获取想法的另一种选择.它的核心只是一个带有专门的__getattribute __(和setattribute)方法的结构化数组.该方法首先尝试正常的数组方法和属性(例如x.shape,x.sum).然后它尝试在定义的字段名中细化attr. def __getattribute__(self,attr): try: return object.__getattribute__(self,attr) except AttributeError: # attr must be a fieldname pass fielddict = ndarray.__getattribute__(self,'dtype').fields try: res = fielddict[attr][:2] except (TypeError,KeyError): raise AttributeError("record array has no attribute %s" % attr) return self.getfield(*res) ... points.view(np.recarray).x成为points.getfield(* points.dtype.fields [‘x’]). 另一种方法是从namedtuple(/usr/lib/python3.4/collections/__init__.py)借用,并定义x和y属性,它们将索引[:,0]和[:,1]列. 2d阵列.??将这些属性添加到np.matrix的子类可能是最容易的,让该类确保大多数数学结果为2d. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |