簡體   English   中英

Python - 為每個元素查找左邊第一個非零元素的索引

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM