Ограничительная коробка массива с периодическими граничными условиями (обтекание) - PullRequest
0 голосов
/ 11 декабря 2019

Я хотел бы сделать что-то похожее на этот вопрос или этот другой вопрос, но с использованием периодических граничных условий (перенос). Я сделаю быстрый пример.

Допустим, у меня есть следующий массив numpy:

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 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 1 1 1 1 0 
0 0 0 0 0 1 0 0 0 0 0 
0 0 0 0 0 1 0 0 0 0 0 
0 0 1 1 1 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 0 0 
0 0 0 0 0 0 0 0 0 0 0 

Затем, используя один из методов, предложенных в двух связанных вопросах, я могу извлечь ограничивающую рамкунулевые значения:

0 0 0 1 1 1 1 1 
0 0 0 1 0 0 0 0 
0 0 0 1 0 0 0 0 
1 1 1 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 0 
0 0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 
1 1 0 0 0 0 0 0 1 1 1 
0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 1 1 1 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 0 0 0 0 0 0 0 0 0 0 

Тогда результат будет:

1 1 0 0 0 0 0 0 1 1 1 
0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 0 0 0 1 0 0 
0 0 0 0 0 1 1 1 1 0 0 

это не то, что я хочу. Я бы хотел, чтобы результат был таким же, как и в предыдущем случае. Я пытаюсь найти разумный способ сделать это, но я застрял. У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 11 декабря 2019

Мы можем адаптировать этот ответ следующим образом:

import numpy as np

def wrapped_bbox(a):
    dims = [*range(1,a.ndim)]
    bb = np.empty((a.ndim,2),int)
    i = 0
    while True:
        n = a.shape[i]
        r = np.arange(1,2*n+1)
        ai = np.any(a,axis=tuple(dims))
        r1_a = np.where(ai,r.reshape(2,n),0).ravel()
        aux = np.maximum.accumulate(r1_a)
        aux = r-aux
        idx = aux.argmax()
        mx = aux[idx]
        if mx > n:
            bb[i] = 0,n
        else:
            bb[i] = idx+1, idx+1 - mx
            if bb[i,0] >= n:
                bb[i,0] -= n
            elif bb[i,1] == 0:
                bb[i,1] = n
        if i == len(dims):
            return bb
        dims[i] -= 1
        i += 1

# example
x = """
......
.x...-
..x...
.....x
"""

x = np.array(x.strip().split())[:,None].view("U1")
x = (x == 'x').view('u1')

print(x)
for r in range(x.shape[1]):
    print(wrapped_bbox(np.roll(x,r,axis=1)))

Выполнить:

[[0 0 0 0 0 0]   # x
 [0 1 0 0 0 0]
 [0 0 1 0 0 0]
 [0 0 0 0 0 1]]
[[1 4]           # bbox vert
 [5 3]]          # bbox horz, note wraparound (left > right)
[[1 4]
 [0 4]]          # roll by 1
[[1 4]
 [1 5]]          # roll by 2
[[1 4]
 [2 6]]          # etc.
[[1 4]
 [3 1]]
[[1 4]
 [4 2]]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...