如何更改numpy中的掩码数组的值? [英] How can I change the value of a masked array in numpy?

查看:168
本文介绍了如何更改numpy中的掩码数组的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,有时我尝试修改掩码数组的值,但是python似乎忽略了这一点.我在想这与将内存存储在数组中的方式有​​关,就好像我在修改值的副本而不是值本身一样,但是我对此并不足够了解,因此不知道如何解析它.

这是我要执行的操作的简化版本:

  x = np.zeros((2,5))#创建二维零数组x [0] [1:3] = 5#将第一维上的某些值替换为5mask =(x [0]> 0)#创建一个掩码以仅处理非负值x [0] [mask] [1] = 10#更改非负值之一print x [0] [mask] [1]#原始数组中的值未更改 

此输出为:

  5.0 

应为10.

任何帮助将不胜感激,理想情况下,这需要可扩展(这意味着我不一定知道x的形状,或者值不是非负值,或者我需要修改哪个值).

我正在ubpy 16.04.2上的python 2.7.12上使用numpy 1.11.0

谢谢!

解决方案

让我们概括一下您的问题:

 在[164]中:x = np.zeros((2,5))在[165]中:x [0,[1,3]] = 5#带有列表而不是切片的索引在[166]中:x出[166]:array([[0.,5.,0.,5.,0.],[0.,0.,0.,0.,0.]]]) 

当索引恰好发生在 = 之前时,它是 __ setitem __ 的一部分,并作用于原始数组.无论索引是使用切片,列表还是布尔掩码,都是如此.

但是带有列表或遮罩的选择会产生一个副本.进一步的索引分配仅影响该副本,而不影响原始副本.

 在[167]中:x [0,[1,3]]Out [167]:array([5.,5.])在[168]中:x [0,[1,3]] [1] = 6在[169]中:x出[169]:array([[0.,5.,0.,5.,0.],[0.,0.,0.,0.,0.]]]) 

解决此问题的最佳方法是修改蒙版本身:

 在[170]中:x [0,np.array([1,3])[1]] = 6在[171]中:x出[171]:array([[0.,5.,0.,6.,0.],[0.,0.,0.,0.,0.]]]) 

如果 mask 为布尔值,则可能需要将其转换为索引数组

 在[174]中:mask = x [0]> 0在[175]中:遮罩Out [175]:数组([False,True,False,True,False],dtype = bool)在[176]中:idx = np.where(mask)[0]在[177]中:idxOut [177]:array([1,3],dtype = int32)在[178]中:x [0,idx [1]]出[178]:6.0 

或者您可以直接调整布尔值

 在[179]中:mask [1] = False在[180]中:x [0,mask]出[180]:数组([6.]) 

因此,在您遇到大问题时,您需要知道何时索引生成视图并且它是副本.而且您需要对带有列表,数组和布尔值的索引感到满意,并了解如何在它们之间进行切换.

In my code, at some point I try to modify a value of a masked array, yet python seems to ignore this. I'm thinking this has to do with the way memory is stored in arrays, as if I were modifying a copy of the value and not the value itself, but I'm not well versed enough in this to have any clue how to resolve it.

Here is a simplified version of what I'm trying to do :

    x = np.zeros((2,5)) # create 2D array of zeroes
    x[0][1:3] = 5       # replace some values along 1st dimension with 5

    mask = (x[0] > 0)   # create a mask to only deal with the non negative values

    x[0][mask][1] = 10  # change one of the values that is non negative 

    print x[0][mask][1] # value isn't changed in the original array

the output of this is :

    5.0

when it should be 10.

Any help would be greatly appreciated, ideally this need to be scalable (meaning I don't necessarily know the shape of x, or where the values are non-negative, or which one I will need to modify).

I'm working with numpy 1.11.0, on python 2.7.12 on Ubuntu 16.04.2

Thanks !

解决方案

Let's generalize your problem a bit:

In [164]: x=np.zeros((2,5))
In [165]: x[0, [1, 3]] = 5      # index with a list, not a slice
In [166]: x
Out[166]: 
array([[ 0.,  5.,  0.,  5.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

When the indexing occurs right before the =, it's part of a __setitem__ and acts on the original array. This is true whether the indexing uses slices, a list or a boolean mask.

But a selection with the list or mask produces a copy. Further indexed assignment affects only that copy, not the original.

In [167]: x[0, [1, 3]]
Out[167]: array([ 5.,  5.])
In [168]: x[0, [1, 3]][1] = 6
In [169]: x
Out[169]: 
array([[ 0.,  5.,  0.,  5.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

The best way around this is to modify the mask itself:

In [170]: x[0, np.array([1,3])[1]] = 6
In [171]: x
Out[171]: 
array([[ 0.,  5.,  0.,  6.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

If the mask is boolean, you may need to convert it to indexing array

In [174]: mask = x[0]>0
In [175]: mask
Out[175]: array([False,  True, False,  True, False], dtype=bool)
In [176]: idx = np.where(mask)[0]
In [177]: idx
Out[177]: array([1, 3], dtype=int32)
In [178]: x[0, idx[1]]
Out[178]: 6.0

Or you can tweak the boolean values directly

In [179]: mask[1]=False
In [180]: x[0,mask]
Out[180]: array([ 6.])

So in your big problem you need to be aware of when indexing produces a view and it is a copy. And you need to be comfortable with index with lists, arrays and booleans, and understand how to switch between them.

这篇关于如何更改numpy中的掩码数组的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆