Как сопоставить таблицу состояний с таблицей жизни в numpy? - PullRequest
2 голосов
/ 12 июля 2020

Проблема и то, что я ожидаю.

У меня есть таблица h, в которой указаны состояния H-связи, где 1 для существующей H-связи, 0 для отсутствия H-связи . Столбцы для разных объектов, строки для разных временных шагов.

0, 0, 1, 1, 0, 0
0, 0, 1, 1, 0, 0
1, 0, 1, 1, 0, 0
1, 1, 1, 1, 0, 1
0, 1, 0, 0, 1, 1
0, 1, 0, 0, 1, 1
1, 0, 1, 1, 0, 1

Я хочу рассчитать жизнь (как долго существует H-связь) для каждого объекта. Таблица ожидаемой продолжительности жизни L должна быть такой.

0, 0, 4, 4, 0, 0
0, 0, 4, 4, 0, 0 
2, 0, 4, 4, 0, 0 
2, 3, 4, 4, 0, 4
0, 3, 0, 0, 2, 4
0, 3, 0, 0, 2, 4
1, 0, 1, 1, 0, 4

Я не знаю, как применить эту карту.

Что я сделал.

Я попытался сопоставить h с новой таблицей generations с указанием поколений H-связи с использованием обнаружения нарастающего фронта. И таблица поколений G получила:

 [[0 0 1 1 0 0]
 [0 0 1 1 0 0]
 [1 0 1 1 0 0]
 [1 1 1 1 0 1]
 [1 1 1 1 1 1]
 [1 1 1 1 1 1]
 [2 1 2 2 1 1]]

И затем я попытался отобразить h в новую таблицу ages, указав возраст Н-связи. Я получил следующую таблицу A.

 [[0 0 1 1 0 0]
 [0 0 2 2 0 0]
 [1 0 3 3 0 0]
 [2 1 4 4 0 1]
 [0 2 0 0 1 2]
 [0 3 0 0 2 3]
 [1 0 1 1 0 4]]

Меня пытались сопоставить h с таблицей выживаемости L с помощью logi c: Срок службы водородной связи - максимум возраст всех возрастов с одним и тем же поколением. Однако я застрял на этом сопоставлении.

Некоторый код

Некоторые коды, которые я использовал для вычисления G и A.

    def getQbGenerations(self, QbStates):
        QbGenerations = np.zeros_like(QbStates, dtype=np.int64)
        Generation = np.zeros(QbStates.shape[-1])
        Generation[QbStates[0] == 1] = 1
        QbGenerations[0] = Generation
        for i in range(1, QbStates.shape[0]):
            # Rising Edge
            RiseMask = np.logical_and(QbStates[i-1]==0, QbStates[i]==1)
            Generation[RiseMask] += 1
            QbGenerations[i] = Generation
        return QbGenerations

    def getQbAges(self, QbStates):
        QbAges = np.zeros_like(QbStates, dtype=np.int64)
        Age = np.zeros(QbStates.shape[-1])
        Age[QbStates[0] == 1] = 1
        QbAges[0] = Age
        for i in range(1, QbStates.shape[0]):
            BondMask = QbStates[i] == 1
            Age[BondMask] += 1
            Age[~BondMask] = 0
            QbAges[i] = Age
        return QbAges

Ответы [ 3 ]

1 голос
/ 15 июля 2020

Благодаря find_runs.py .

Другой ответ:

import numpy as np


def find_runs(x):
    """Find runs of consecutive items in an array."""
    # ensure array
    x = np.asanyarray(x)
    if x.ndim != 1:
        raise ValueError('only 1D array supported')
    n = x.shape[0]

    # handle empty array
    if n == 0:
        return np.array([]), np.array([]), np.array([])

    else:
        # find run starts
        loc_run_start = np.empty(n, dtype=bool)
        loc_run_start[0] = True
        np.not_equal(x[:-1], x[1:], out=loc_run_start[1:])
        run_starts = np.nonzero(loc_run_start)[0]

        # find run values
        run_values = x[loc_run_start]

        # find run lengths
        run_lengths = np.diff(np.append(run_starts, n))

        return run_values, run_starts, run_lengths


if __name__ == "__main__":
    QbStates = np.array([
                    [0, 0, 1, 1, 0, 0],
                    [0, 0, 1, 1, 0, 0],
                    [1, 0, 1, 1, 0, 0],
                    [1, 1, 1, 1, 0, 1],
                    [0, 1, 0, 0, 1, 1],
                    [0, 1, 0, 0, 1, 1],
                    [1, 0, 1, 1, 0, 1]])

    print('QbStates: \n{}'.format(QbStates))
    lifes = np.array([], dtype=np.int64).reshape(0,QbStates.shape[0])
    for row in QbStates.T:
        values, positions, times = find_runs(row)
        life = np.array([],dtype=np.int64)
        for v, t in zip(values, times):
            life = np.append(life, np.repeat(v*t,t))
        lifes = np.vstack([lifes, life])
    
    # Transpose to get the answer
    print('LifeStates:\n {}'.format(lifes.T))

Полученный результат.

QbStates: 
[[0 0 1 1 0 0]
 [0 0 1 1 0 0]
 [1 0 1 1 0 0]
 [1 1 1 1 0 1]
 [0 1 0 0 1 1]
 [0 1 0 0 1 1]
 [1 0 1 1 0 1]]
LifeStates:
 [[0 0 4 4 0 0]
 [0 0 4 4 0 0]
 [2 0 4 4 0 0]
 [2 3 4 4 0 4]
 [0 3 0 0 2 4]
 [0 3 0 0 2 4]
 [1 0 1 1 0 4]]
0 голосов
/ 14 июля 2020

Обратите внимание, что вы получили массив A, мы можем продолжить с A. Если использовать алгоритм, основанный на градиенте по оси кадра, то мы можем получить ожидаемый массив L.

# The array: Age
A= np.array([[0,0,1,1,0,0],
 [0,0,2,2,0,0],
 [1,0,3,3,0,0],
 [2,1,4,4,0,1],
 [0,2,0,0,1,2],
 [0,3,0,0,2,3],
 [1,0,1,1,0,4]])

# Define two parameters
age = A.T
n = age.shape[0]
m = age.shape[1]

# Generate the gradient along frame-axis for the array A
# output: a new array grad_age
grad_age = np.zeros((n, m))
for i in range(n):
    for j in range(m):
        if j < m-1:
            grad_age[i][j] = age[i][j+1] - age[i][j]
        else: # In the old version, this condition was neglected.
            grad_age[i][m-1] = 0 - age[i][m-1]
            
print("The array grad_age:")            
print(grad_age)

# Find out the locations of elements in the array 'age' 
# which are of negative gradient and modify related 
# elements in the array 'age'

for i in range(n):
    for j in reversed(range(m)):       
        t = grad_age[i][j]
        if t < 0:     #find out these index where gradient < 0
            print(t) # for checking
            for x in range(abs(int(t))):
                age[i][j-x] += x
print("The array L:")                
print(age.T)

Результат:

The array grad_age:
[[ 0.  1.  1. -2.  0.  1. -1.]
 [ 0.  0.  1.  1.  1. -3.  0.]
 [ 1.  1.  1. -4.  0.  1. -1.]
 [ 1.  1.  1. -4.  0.  1. -1.]
 [ 0.  0.  0.  1.  1. -2.  0.]
 [ 0.  0.  1.  1.  1.  1. -4.]]
-1.0
-2.0
-3.0
-1.0
-4.0
-1.0
-4.0
-2.0
-4.0
The array L:
[[0 0 4 4 0 0]
 [0 0 4 4 0 0]
 [2 0 4 4 0 0]
 [2 3 4 4 0 4]
 [0 3 0 0 2 4]
 [0 3 0 0 2 4]
 [1 0 1 1 0 4]]
0 голосов
/ 12 июля 2020

Я бы сделал что-то гораздо более простое, хотя и не самое "pythoni c" решение. Я бы использовал следующий алгоритм:

  1. Проведите каждый столбец

  2. L oop через столбец, пока не будет достигнута ненулевая запись

  3. Запишите, как долго «полоса» ненулевых записей составляет

  4. Добавить в список

  5. Отн. oop через столбец

  6. Определить первую полосу

  7. Измените значения в первой полосе на первую запись в списке выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...