基于条件切片2D numpy数组

时间:2014-11-26 16:16:47

标签: arrays python-2.7 numpy slice

我有一个numpy数组

import numpy as np

a = np.array([
[999, 999, 999, 999, 999, 999, 999, 999, 999, 999],
[999, 999, 999, 1, 2, 3, 4, 999, 999, 999],
[999, 999, 999, 5, 6, 7, 8, 999, 999, 999],
[999, 999, 999, 9, 10, 11, 12, 999, 999, 999],
[999, 999, 999, 999, 999, 999, 999, 999, 999, 999]])

如何使用numpy切片返回过滤后的值,仅包含不同于999的值?

filtered = np.where(a != 999)
In [5]: filtered
Out[5]: 
(array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
    2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4,
    4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
    6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9,
    9, 9, 9, 9, 9, 9, 9, 9]),
 array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
    3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
    6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8,
    9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
    2, 3, 4, 5, 6, 7, 8, 9]))

期望的输出:

output = np.array([
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]])

3 个答案:

答案 0 :(得分:1)

你的是一个特殊情况,因为子阵列是矩形的。您可以使用花式索引获取平面值:

>>> a[filtered]
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])

如果你已经知道了形状,你可以重塑一下:

>>> a[filtered].reshape(3,4)
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

但是,在一般情况下,无法保证输入数据在过滤后会留下矩形数组。例如,考虑输入数组有a[0,0] == 13时输出数组应该是什么样子。

答案 1 :(得分:1)

您可以执行以下操作:

>>> mask = (a!=999)
>>> dim1 = np.any(mask, axis=1).sum()
>>> a[mask].reshape(dim1, -1)
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])

这当然假设您在整个数组中只有一个连续的框。

答案 2 :(得分:0)

您也可以这样做。使用条件创建2D蒙版。根据条件将条件掩码类型转换为int或float,并将其与原始数组相乘。

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])