在Numpy中查找非零值/索引

时间:2019-05-31 08:47:22

标签: python python-3.x numpy

我有一个很大的numpy数组,其形状为(12388,4)。前两个值是坐标,后两个键值。其中一些为零。我想筛选整个数组,并找到其中后两个值都不为零的所有索引。 我的代码如下:

slice_index,_ = np.where((slice[:,2:4]!=0))
slice_nonzero_values = slice[slice_index]

结果数组slice_nonzero_values的形状为(18550,4)。因此,一定有问题,因为结果数组比原始数组大。看着csv,我发现如果slice [:,2]和slice [:,3]都不为零,则np.where会多次返回相同的索引。因此,我尝试了includenp.unique:

slice_index,_ = np.where((slice[:,2:4]!=0))
slice_index_unique = np.unique(slice_index)
slice_nonzero_values = slice[slice_index_unique]

这将导致形状为(9669,4)。看起来好多了。但是,为了确保现在一切正常,我进行了以下循环:

    test = []
    test_index = []
    for index, i in enumerate(slice):
        if i[2]!=0 or i[3]!=0:
            test.append(i)
            test_index.append(index)
    test = np.array(test)
    test_index = np.array(test_index)

此循环导致数组测试的形状为(8881,4)。现在,我完全困惑两种方法中的哪一种是正确的。根据循环的逻辑,测试数组必须是最严格的。但是,这只是字面量的切片数组。我不能离开循环。总结一下:我想过滤切片数组,并获取最后两列中任一列均具有非零值的所有条目。换句话说,如果两个值(slice [:,2]和slice [:,3])均为零,则该行退出。如果它们中只有一个为零,而另一个不是零,就可以了。

这是切片数组的示例:

   array([[0.01032591, 0. , 0.               , 0.        ],
   [0.03256559, 0.00890732, 5.0000000e+00    , 0.        ],
   [0.0468626 , 0.01543951, 0.               , 0.        ],
   ...,
   [0.13899946, 0.8847985 , 0.               , 0.        ],
   [0.13899946, 0.8847985 , 4.0000000e+00    , 5.3900000e+02],
   [0.13899946, 0.8847985 , 0.               , 0.        ]], dtype=float32)

1 个答案:

答案 0 :(得分:1)

这是一个正在运行的演示。创建测试数据:

import numpy as np

X = np.random.rand(10,4)
X = np.vstack([X, np.zeros([2,4])])

>>> X
array([[0.09889965, 0.01169015, 0.30886119, 0.40204571],
       [0.67277149, 0.01654403, 0.17710642, 0.54201684],
       # ...
       [0.        , 0.        , 0.        , 0.        ],
       [0.        , 0.        , 0.        , 0.        ]])

查找向量的后两个数字都不为零:

idx = np.where(np.sum(X[:,2:], axis=1) != 0)[0]

# alternatively, use np.any
idx = np.where(np.any(X[:,2:], axis=1))[0]

检索过滤的向量:

X_none_zeros = X[idx]

>>> X_none_zeros
array([[0.09889965, 0.01169015, 0.30886119, 0.40204571],
       # ...
       [0.78279739, 0.84191242, 0.31685306, 0.54906034]])

>>> X_none_zeros.shape
(10, 4)

>>> X.shape
(12, 4)

说明:实际代码只有两行:

# retrieve last 2 numbers for each vector in X
# and sum each vector horizontally, so you have 
# [s1, s2, s3, ...]
# use the condition to filter indexes
idx = np.where(np.sum(X[:,2:], axis=1) != 0)[0]
# retrieve matched vectors accordingly
X_none_zeros = X[idx]