Python 如何正确屏蔽 numpy 二维数组?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38193958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 20:29:04  来源:igfitidea点击:

How to properly mask a numpy 2D array?

pythonnumpymatrixmaskmasked-array

提问by Anonymous

Say I have a two dimensional array of coordinates that looks something like

假设我有一个二维坐标数组,看起来像

x = array([[1,2],[2,3],[3,4]])

x = array([[1,2],[2,3],[3,4]])

Previously in my work so far, I generated a mask that ends up looking something like

到目前为止,在我的工作中,我生成了一个最终看起来像的面具

mask = [False,False,True]

mask = [False,False,True]

When I try to use this mask on the 2D coordinate vector, I get an error

当我尝试在 2D 坐标向量上使用此蒙版时,出现错误

newX = np.ma.compressed(np.ma.masked_array(x,mask))

>>>numpy.ma.core.MaskError: Mask and data not compatible: data size 
   is 6, mask size is 3.`

which makes sense, I suppose. So I tried to simply use the following mask instead:

我想这是有道理的。所以我尝试简单地使用以下掩码:

mask2 = np.column_stack((mask,mask))
newX = np.ma.compressed(np.ma.masked_array(x,mask2))

And what I get is close:

我得到的很接近:

>>>array([1,2,2,3])

>>>array([1,2,2,3])

to what I would expect (and want):

我所期望的(和想要的):

>>>array([[1,2],[2,3]])

>>>array([[1,2],[2,3]])

There must be an easier way to do this?

必须有更简单的方法来做到这一点?

采纳答案by Psidom

Is this what you are looking for?

这是你想要的?

import numpy as np
x[~np.array(mask)]
# array([[1, 2],
#        [2, 3]])

Or from numpy masked array:

或者从numpy 掩码数组

newX = np.ma.array(x, mask = np.column_stack((mask, mask)))
newX

# masked_array(data =
#  [[1 2]
#  [2 3]
#  [-- --]],
#              mask =
#  [[False False]
#  [False False]
#  [ True  True]],
#        fill_value = 999999)

回答by hpaulj

Your xis 3x2:

x是 3x2:

In [379]: x
Out[379]: 
array([[1, 2],
       [2, 3],
       [3, 4]])

Make a 3 element boolean mask:

制作一个 3 元素布尔掩码:

In [380]: rowmask=np.array([False,False,True])

That can be used to select the rows where it is True, or where it is False. In both cases the result is 2d:

这可用于选择为 True 或为 False 的行。在这两种情况下,结果都是 2d:

In [381]: x[rowmask,:]
Out[381]: array([[3, 4]])

In [382]: x[~rowmask,:]
Out[382]: 
array([[1, 2],
       [2, 3]])

This is without using the MaskedArray subclass. To make such array, we need a mask that matches xin shape. There isn't provision for masking just one dimension.

这是不使用 MaskedArray 子类的。为了制作这样的数组,我们需要一个x形状匹配的掩码。没有规定仅屏蔽一维。

In [393]: xmask=np.stack((rowmask,rowmask),-1)  # column stack

In [394]: xmask
Out[394]: 
array([[False, False],
       [False, False],
       [ True,  True]], dtype=bool)

In [395]: np.ma.MaskedArray(x,xmask)
Out[395]: 
masked_array(data =
 [[1 2]
 [2 3]
 [-- --]],
             mask =
 [[False False]
 [False False]
 [ True  True]],
       fill_value = 999999)

Applying compressedto that produces a raveled array: array([1, 2, 2, 3])

应用compressed到它会产生一个散乱的数组:array([1, 2, 2, 3])

Since masking is element by element, it could mask one element in row 1, 2 in row 2 etc. So in general compressing, removing the masked elements, will not yield a 2d array. The flattened form is the only general choice.

由于屏蔽是逐个元素进行的,它可以屏蔽第 1 行中的一个元素,第 2 行中的第 2 行等。因此,通常compressing,删除被屏蔽的元素不会产生二维数组。扁平形式是唯一的通用选择。

np.mamakes most sense when there's a scattering of masked values. It isn't of much value if you want want to select, or deselect, whole rows or columns.

np.ma当掩码值分散时最有意义。如果您想选择或取消选择整行或整列,它没有多大价值。

===============

================

Here are more typical masked arrays:

以下是更典型的掩码数组:

In [403]: np.ma.masked_inside(x,2,3)
Out[403]: 
masked_array(data =
 [[1 --]
 [-- --]
 [-- 4]],
             mask =
 [[False  True]
 [ True  True]
 [ True False]],
       fill_value = 999999)

In [404]: np.ma.masked_equal(x,2)
Out[404]: 
masked_array(data =
 [[1 --]
 [-- 3]
 [3 4]],
             mask =
 [[False  True]
 [ True False]
 [False False]],
       fill_value = 2)

In [406]: np.ma.masked_outside(x,2,3)
Out[406]: 
masked_array(data =
 [[-- 2]
 [2 3]
 [3 --]],
             mask =
 [[ True False]
 [False False]
 [False  True]],
       fill_value = 999999)

回答by CrossEntropy

Since none of these solutions worked for me, I thought to write down what solution did, maybe it will useful for somebody else. I use python 3.x and I worked on two 3D arrays. One, which I call data_3Dcontains float values of recordings in a brain scan, and the other, template_3Dcontains integers which represent regions of the brain. I wanted to choose those values from data_3Dcorresponding to an integer region_codeas per template_3D:

由于这些解决方案都不适合我,我想写下解决方案的作用,也许对其他人有用。我使用 python 3.x 并且我处理了两个 3D 数组。一个,我称之为data_3D包含脑部扫描记录的浮点值,另一个template_3D包含代表大脑区域的整数。我想从选择那些值data_3D对应一个整数region_codetemplate_3D

my_mask = np.in1d(template_3D, region_code).reshape(template_3D.shape)
data_3D_masked = data_3D[my_mask]

which gives me a 1D array of only relevant recordings.

这给了我一个只有相关录音的一维数组。

回答by Warren Weckesser

In your last example, the problem is not the mask. It is your use of compressed. From the docstring of compressed:

在您的最后一个示例中,问题不在于掩码。这是你的用途compressed。从文档字符串compressed

Return all the non-masked data as a 1-D array.

So compressedflattens the nonmasked values into a 1-d array. (It has to, because there is no guarantee that the compressed data will have an n-dimensional structure.)

因此compressed将非屏蔽值展平为一维数组。(必须如此,因为不能保证压缩数据将具有 n 维结构。)

Take a look at the masked array before you compress it:

在压缩之前先看一下掩码数组:

In [8]: np.ma.masked_array(x, mask2)

Out[8]: 
masked_array(data =
 [[1 2]
 [2 3]
 [-- --]],
             mask =
 [[False False]
 [False False]
 [ True  True]],
       fill_value = 999999)

回答by Mendi Barel

With np.whereyou can do all sorts of things:

有了np.where你,你可以做各种各样的事情:

x_maskd = np.where(mask, x, 0)