python numpy 获取屏蔽数据而不压平

标签 python arrays numpy mask

如何仅获取屏蔽数据而不将数据展平为一维数组?也就是说,假设我有一个 numpy 数组

a = np.array([[0, 1, 2, 3],
              [0, 1, 2, 3],
              [0, 1, 2, 3]])

并且我屏蔽所有大于 1 的元素,

b = ma.masked_greater(a, 1)

masked_array(data =
 [[0 1 -- --]
 [0 1 -- --]
 [0 1 -- --]],
             mask =
 [[False False  True  True]
 [False False  True  True]
 [False False  True  True]],
       fill_value = 999999)

如何仅获取屏蔽元素而不展平输出?也就是说,我需要得到

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

最佳答案

让我们尝试一个产生参差不齐的结果的示例 - 每行中有不同数量的“屏蔽”值。

In [292]: a=np.arange(12).reshape(3,4)
In [293]: a
Out[293]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [294]: a<6
Out[294]: 
array([[ True,  True,  True,  True],
       [ True,  True, False, False],
       [False, False, False, False]], dtype=bool)

与此条件匹配的值的扁平列表。它无法返回常规的二维数组,因此它必须恢复为扁平数组。

In [295]: a[a<6]
Out[295]: array([0, 1, 2, 3, 4, 5])

做同样的事情,但是逐行迭代

In [296]: [a1[a1<6] for a1 in a]
Out[296]: [array([0, 1, 2, 3]), array([4, 5]), array([], dtype=int32)]

尝试创建结果数组会生成一个对象类型数组,它只不过是数组包装器中的列表:

In [297]: np.array([a1[a1<6] for a1 in a])
Out[297]: array([array([0, 1, 2, 3]), array([4, 5]), array([], dtype=int32)], dtype=object)

结果参差不齐这一事实很好地表明,通过一个向量化操作来执行该操作即使不是不可能,也是很困难的。


这是生成数组列表的另一种方法。通过 sum,我可以找到每行中有多少个元素,然后使用它来 扁平化数组拆分为子列表。

In [320]: idx=(a<6).sum(1).cumsum()[:-1]
In [321]: idx
Out[321]: array([4, 6], dtype=int32)
In [322]: np.split(a[a<6], idx)
Out[322]: [array([0, 1, 2, 3]), array([4, 5]), array([], dtype=float64)]

它确实使用了“扁平化”。对于这些小例子,它比行迭代慢。 (不用担心空 float 组,split 必须构造一些东西并使用默认的数据类型。)


没有空行的不同掩码清楚地显示了两种方法的等效性。

In [344]: mask=np.tri(3,4,dtype=bool)  # lower tri
In [345]: mask
Out[345]: 
array([[ True, False, False, False],
       [ True,  True, False, False],
       [ True,  True,  True, False]], dtype=bool)
In [346]: idx=mask.sum(1).cumsum()[:-1]
In [347]: idx
Out[347]: array([1, 3], dtype=int32)
In [348]: [a1[m] for a1,m in zip(a,mask)]
Out[348]: [array([0]), array([4, 5]), array([ 8,  9, 10])]
In [349]: np.split(a[mask],idx)
Out[349]: [array([0]), array([4, 5]), array([ 8,  9, 10])]

关于python numpy 获取屏蔽数据而不压平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34468436/

相关文章:

python - 复制列表值并将新列添加到数据框

java - Double 与双数组上的 Arrays.asList().contains()

python - 如何迭代生成集合中所有可能的元素组合

python - 如何让 raw_input 重复直到我想退出?

python - 如何在python中转义正则表达式的所有特殊字符

ios - 组合多个数组。快速调试 xcode

java - 为什么程序不给我数组的最小值?

python - 在转换为 numpy 重新数组时处理 None 值

numpy - SparkSQL 过滤函数不适用于 NaN

c++ - Python.h 的 undefined symbol