簡體   English   中英

如何在二維 numpy 數組中找到最長連續出現的非零元素

[英]How to find longest consecutive ocurrence of non-zero elements in 2D numpy array

我在 2D 網格上模擬蛋白質折疊,其中每個角度都是 ±90° 或 0°,並且有以下問題:

我有一個用零填充的 n×n numpy 數組,除了某些地方的值是從 1 到 n 的任何整數。 每個整數只出現一次。 整數 k 始終是 k-1k + 1 的最近鄰,端點除外。 該數組被保存為類 Grid 中的一個對象,我創建該類用於進行能量計算和折疊蛋白質。 示例數組,n=5:

>>> from Grid import Grid
>>> a = Grid(5)
>>> a.show()
[[0 0 0 0 0]
 [0 0 0 0 0]
 [1 2 3 4 5]
 [0 0 0 0 0]
 [0 0 0 0 0]]

我的目標是找到最長的連續非零元素行,沒有任何彎曲。 在上述情況下,結果應為 5。

到目前為止,我的想法是這樣的:

def getDiameter(self):
    indexes = np.zeros((self.n, 2))
    for i in range(1, self.n + 1):
        indexes[i - 1] = np.argwhere(self.array == i)[0]

    for i in range(self.n):
         j = 1
        currentDiameter = 1
            while indexes[0][i] == indexes[0][i + j] and i + j <= self.n:
                currentDiameter += 1
                j += 1

        while indexes[i][0] == indexes[i + j][0] and i + j <= self.n:
            currentDiameter += 1
            j += 1

        if currentDiameter > diameter:
            diameter = currentDiameter

     return diameter

這有兩個問題:(1)它不起作用,(2)如果我讓它工作,它的效率會非常低。 我想知道是否有人有更好的方法來做到這一點。 如果有什么不清楚的,請告訴我。

編輯:不太簡單的例子

[[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0 10  0  0  0]
[ 0  0  0  0  0  0  9  0  0  0]
[ 0  0  0  0  0  0  8  0  0  0]
[ 0  0  0  4  5  6  7  0  0  0]
[ 0  0  0  3  0  0  0  0  0  0]
[ 0  0  0  2  1  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]
[ 0  0  0  0  0  0  0  0  0  0]] 

這里的正確答案是 4(最長的列和最長的行都有四個非零元素)。

我從您的問題中了解到,您需要找到 numpy 數組中連續元素的最長出現次數(逐行)。

所以對於下面的這個,輸出應該是5

[[1 2 3 4 0]
 [0 0 0 0 0]
 [10 11 12 13 14]
 [0 1 2 3 0]
 [1 0 0 0 0]]

因為[10 11 12 13 14]是連續元素,並且與任何其他行中的任何連續元素相比,它們的長度最長。

如果這是您的期望,請考慮:

import numpy as np
from itertools import groupby

a = np.array([[1, 2, 3, 4, 0],
 [0, 0, 0, 0, 0],
 [10, 11, 12, 13, 14],
 [0, 1, 2, 3, 0],
 [1, 0, 0, 0, 0]])

a = a.astype(float)
a[a == 0] = np.nan
b = np.diff(a)      # Calculate the n-th discrete difference. Consecutive numbers will have a difference of 1.
counter = []
for line in b:       # for each row.
    if 1 in line:    # consecutive elements differ by 1.
        counter.append(max(sum(1 for _ in g) for k, g in groupby(line) if k == 1) + 1)  # find the longest length of consecutive 1's for each row.
print(max(counter))  # find the max of list holding the longest length of consecutive 1's for each row.
# 5

對於您的特定示例:

[[0 0 0 0 0] 
[0 0 0 0 0] 
[1 2 3 4 5] 
[0 0 0 0 0] 
[0 0 0 0 0]]
# 5

首先查找列表中最長的連續出現:

def find_longest(l):
    counter = 0
    counters =[]
    for i in l:
        if i == 0:
            counters.append(counter)
            counter = 0
        else:
            counter += 1
    counters.append(counter)
    return max(counters)

現在您可以將此函數應用於數組的每一行和每一列,並找到最大值:

longest_occurrences = [find_longest(row) for row in a] + [find_longest(col) for col in a.T]
longest_occurrence = max(longest_occurrences)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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