就地修改NumPy recarray的高级索引子集
我有一个叫做recarray的数组,里面有几个列,我用它来选择一部分数据。大概是这样的:
>>> x
array([ ('label1',True,3),
('label2',True,2),
('label1',False,4)],
dtype=[('status', '|S16'), ('select', '|b1'), ('somedata', '<i4')])
我从这个数组中选择数据的方法有点像之前在StackOverflow上提到的一个问题。
condit=(x['status']=='label1')&(x['select']==True)
x_subids=numpy.where(condit)[0]
x_sub=x[x_subids]
然后我会对选出来的这部分数据进行一些处理,并更新原来的数据。
x[x_subids]=x_sub
我知道因为使用了高级索引,所以x_sub
是一个副本,而不是原来的视图。我在想有没有什么简单的方法,可以避免创建这个数组的副本,直接在原数组上操作,同时又能满足我需要选择数据的条件。
2 个回答
2
你可以使用一个“掩码数组”:
masked = numpy.ma.array(x,
mask=(x['status']!='label1')|(x['select']!=True),
copy=False)
注意,这里的掩码是你的 condit
的反转,因为掩码为 True
的地方会被隐藏。现在你可以对这个掩码数组使用任何 numpy 的通用函数,只有那些没有被隐藏的值会受到影响。
3
你提到的那些修改,可以通过numpy.place()
函数来实现:
>>> import numpy >>> x = numpy.array([("label1",True,3), ("label2",False,2), ("label1",True,4)], ... dtype=[("status", "|S16"), ("select", "|b1"), ("somedata", ">> mask = x["select"] >>> numpy.place(x["somedata"], mask, (5, 6)) >>> print x [('label1', True, 5) ('label2', False, 2) ('label1', True, 6)] >>> numpy.place(x["status"], mask, "label3") >>> print x [('label3', True, 5) ('label2', False, 2) ('label3', True, 6)]
注意以下几点:
为了举个合适的例子,我稍微改了一下数值和条件。
这次,
mask
为True
的值又被选出来了,而不是像我之前的回答那样被屏蔽掉。在你的条件
condit
中,==True
这一部分是多余的,可以去掉哦 :)