我知道有很多类似的问题,但这明显不同。
给出诸如row = [1 0 0 1 0 1 0 1]
之类的任何行,我要输出显示output = [0 -1 -1 0 -1 3 -1 5]
的行
基本上这就是说,前一个1指向自身。具有索引3的第二个1
指向左侧的1
,并且由于1
的索引为0,所以它为0。第三个1
指向左边的1
的索引为3。最后,第四个1
指向左边的索引为5
的第一个。最后,所有0
都设置为-1。
我能够获得所有1
正在使用numpy.nonzero(row)
的位置的索引,但是我不确定如何在与输入数组相同的维度上分隔这些索引。
答案 0 :(得分:3)
如果您在列表上进行迭代(也使用enumerate
来跟踪元素索引)并存储最后一个在看到1(在任何非零值之下)的索引(第一个索引除外),这很容易时间)
row = [1, 0, 0, 1, 0, 1, 0, 1]
prev_index = None
result = []
for i,v in enumerate(row):
if v:
result.append(i if prev_index is None else prev_index)
prev_index = i
else:
result.append(-1)
>>> result
[0, -1, -1, 0, -1, 3, -1, 5]
由于需要存储先前的索引,因此很难通过列表理解来实现。
答案 1 :(得分:2)
如果我正确理解的话,基本上我们想要用0
替换所有-1
,并将所有非零替换为前一个零的索引。
因此,我们可以创建一个-1
数组,其长度与给定数组相同,然后用np.where
的结果替换零视图:
outp = np.full(a.shape, -1)
idxs = a.nonzero()
if len(idxs) > 0:
outp[idxs] = np.concatenate(([0], idxs[0][:-1]))
例如:
>>> a = np.array([1, 0, 0, 1, 0, 1, 0, 1])
>>> outp = np.full(a.shape, -1)
>>> idxs = a.nonzero()
>>> outp[idxs] = np.concatenate(([0], idxs[0][:-1]))
>>> outp
array([ 0, -1, -1, 0, -1, 3, -1, 5])
但是,如果第一个值是零,它将仍然具有值-1
,因此索引范围超出范围,但是至少对于我来说,尚不清楚在那种情况下会发生什么。
我们可以这样写:
outp = np.full(a.shape, -1)
idxs, = a.nonzero()
if len(idxs) > 0:
outp[idxs[1:]] = idxs[:-1]
outp[idxs[0]] = idxs[0]
这使我们可以在第一个非零之前的 之前填充值:
outp = np.full(a.shape, -1)
idxs, = a.nonzero()
if len(idxs) > 0:
outp[idxs[1:]] = idxs[:-1]
outp[idxs[0]] = idxs[0]
outp[:idxs[0]] = 0 # or another value before the first non-zero
答案 2 :(得分:0)
使用列表理解。
row = [1, 0, 0, 1, 0, 1, 0, 1]
output = [idx-(idx!=0)-list(reversed(row[:max(idx, 1)])).index(1) if i else -1 for idx, i in enumerate(row)]
print(output) # -> [0, -1, -1, 0, -1, 3, -1, 5]