如何在numpy中将状态表映射到生命表?

2024-04-28 22:42:18 发布

您现在位置:Python中文网/ 问答频道 /正文

问题和我的期望

我有一个表h,它表示氢键状态,其中1表示现有氢键,0表示不存在氢键。列用于不同的对象,行用于不同的时间步长

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

我想计算每个物体的寿命(氢键存在的时间)。所以预期寿命表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,该表使用上升沿检测来指示氢键的生成。并且生成表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: 氢键的寿命是同一代人所有年龄中的最大年龄。然而,我一直坚持这个映射

一些代码

我用来计算GA的一些代码

    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

Tags: 代码agedefnp时间zerosgenerationshape
3条回答

多亏了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]]

我会做一些简单得多的事情,尽管不是最“pythonic”的解决方案。我将使用以下算法:

  1. 以每一列为例

  2. 循环遍历列,直到到达非零条目

  3. 记录非零条目的“条纹”持续时间

  4. 将此添加到列表中

  5. 重新打开该列

  6. 识别第一条条纹

  7. 将第一条条纹中的值更改为上面列表中的第一个条目

注意,您已经获得了数组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]]

相关问题 更多 >