[英]Python - Finding indices of the first non-zero element to the left for each element
我知道有很多類似的問題,但這個問題有些不同。
給定任何行如row = [1 0 0 1 0 1 0 1]
我想輸出一行表示output = [0 -1 -1 0 -1 3 -1 5]
基本上這就是說,第一個,指向自己。 第二個1
,其索引為3,指向其左邊的1
,因為那個1
的索引為0,所以它為0.第3 1
指向左邊的1
,其中有索引3.最后,第4個1
指向左邊第一個有索引5
。 最后,所有0
都設置為-1。
我能夠得到所有1
使用numpy.nonzero(row)
的索引,但我不知道如何在與輸入數組相同的維度中numpy.nonzero(row)
這些索引。
如果你在列表上進行迭代(使用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
替換所有0
,並且如果我理解正確的話,將所有非零替換為前一個零的索引。
因此,我們可以創建一個-1
s的數組,其長度與給定數組相同,然后用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
使用列表理解。
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]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.