Modifying an advanced-indexed subset of a NumPy recarray in place
I have a recarray with a couple columns that I use for selecting a subset. Something like
>>> x
array([ ('label1',True,3),
('label2',True,2),
('label1',False,4)],
dtype=[('status', '|S16'), ('select', '|b1'), ('somedata', '<i4')])
Data is selected from this array using an approach similar to a previous SO question.
condit=(x['status']=='label1')&(x['select']==True)
x_subids=numpy.where(condit)[0]
x_sub=x[x_subids]
Then I do some work on the subset and update the original.
x[x_subids]=x_sub
I understand that x_sub
is a copy ra开发者_Go百科ther than a view due to advanced indexing, and I was wondering if there was an elegant way of avoiding the array copy and just working with the original given the conditions that I need to subset the data.
The kind of modifications you mention in the comments to my first answer can be done with the numpy.place()
function:
>>> 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)]
Note that
I changed the values and conditions a bit for the sake of a pertinent example.
This time, the values where
mask
isTrue
are selected again, not masked out as in my previous answer.The
==True
part in your maskcondit
is redundant, just leave it out :)
You could use a "masked array":
masked = numpy.ma.array(x,
mask=(x['status']!='label1')|(x['select']!=True),
copy=False)
Note that the mask is the inverse of your condit
, since the values where the mask is True
are masked out. You can now apply any numpy ufunc to this masked array, and only the values not masked out are affected.
精彩评论