【发布时间】:2017-03-10 13:19:57
【问题描述】:
问题
我有一个一维 numpy 数组,其中大部分填充了零,但也包含一些非零值组。
>> import numpy as np
>> a = np.zeros(10)
>> a[2:4] = 2
>> a[6:9] = 3
>> print a
[ 0. 0. 2. 2. 0. 0. 3. 3. 3. 0.]
我想获取仅包含最后一个非零组的数组。换句话说,除了最后一个非零组之外的所有组都应该被零替换。 (这些组可能只有 1 个元素长)。像这样:
[ 0. 0. 0. 0. 0. 0. 3. 3. 3. 0.]
非稳健解决方案
这似乎可以解决问题。反转数组并找到元素之间变化为负的第一个索引。然后用零替换所有后续元素。然后翻回来。有点啰嗦:
>> b = a[::-1]
>> b[np.where(np.ediff1d(b) < 0)[0][0] + 1:] = 0
>> c = b[::-1]
>> print c
[ 0. 0. 0. 0. 0. 0. 3. 3. 3. 0.]
在特定情况下失败
但是,它并不健壮并且在以下情况下会失败(因为 where 命令返回一个空的索引列表):
>> a = np.zeros(10)
>> a[0:4] = 2
>> print a
[ 2. 2. 2. 2. 0. 0. 0. 0. 0. 0.]
>> b = a[::-1]
>> b[np.where(np.ediff1d(b) < 0)[0][0] + 1:] = 0
>> c = b[::-1]
>> print c
Traceback (most recent call last):
File "<ipython-input-81-8cba57558ba8>", line 1, in <module>
runfile('C:/Users/name/test1.py', wdir='C:/Users/name')
File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile
execfile(filename, namespace)
File "C:\ProgramData\Anaconda2\lib\site-packages\spyder\utils\site\sitecustomize.py", line 87, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)
File "C:/Users/name/test1.py", line 21, in <module>
b[np.where(np.ediff1d(b) < 0)[0][0] + 1:] = 0
IndexError: index 0 is out of bounds for axis 0 with size 0
修复
所以我需要引入一个if 子句:
>> b = a[::-1]
>> if len(np.where(np.ediff1d(b) < 0)[0]) > 0:
>> b[np.where(np.ediff1d(b) < 0)[0][0] + 1:] = 0
>> c = b[::-1]
>> print c
[ 2. 2. 2. 2. 0. 0. 0. 0. 0. 0.]
有没有更优雅的方法呢?
更新 继 Divakar 的出色回答和 mtrw 的问题之后,我想扩展规范。如果输入数组的非零值为负和,则该方法也应该适用于在分组内发生变化的非零数字组。
例如np.array([1, 0, 0, 4, 5, 4, 5, 0, 0])
这意味着我们检查元素之间的正或负差异以找到组边界的方法效果不佳。
【问题讨论】:
-
非零值是否也保证大于0?
标签: numpy