转移概率矩阵

2021-01-26 07:30:31 发布

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

我有以下数组:

a=[['A', 'B'],
 ['B', 'B'],
 ['B', 'C'],
 ['C', 'B'],
 ['B', 'A'],
 ['A', 'D'],
 ['D', 'D'],
 ['D', 'A'],
 ['A', 'B'],
 ['B', 'A'],
 ['A', 'D']]

我想做一个转移概率矩阵,这样我得到:

^{pr2}$

在图中,{{cd2>中,有多少个

from collections import Counter
Counter(tuple(x) for x in l)

它将数组的元素正确计数为:

Counter({('A', 'B'): 2,
         ('B', 'B'): 1,
         ('B', 'C'): 1,
         ('C', 'B'): 1,
         ('B', 'A'): 2,
         ('A', 'D'): 2,
         ('D', 'D'): 1,
         ('D', 'A'): 1})

所以矩阵应该是

[[0,2/5,0,2/5],[2/4,1/4,1/4,0],[0,1,0,0],[1/2,0,0,1/2]]

3条回答
网友
1楼 ·

基于熊猫的解决方案:

import pandas as pd
from collections import Counter
# Create a raw transition matrix
matrix = pd.Series(Counter(map(tuple, a))).unstack().fillna(0)
# Normalize the rows
matrix.divide(matrix.sum(axis=1),axis=0)
#     A     B     C    D
#A  0.0  0.50  0.00  0.5
#B  0.5  0.25  0.25  0.0
#C  0.0  1.00  0.00  0.0
#D  0.5  0.00  0.00  0.5
网友
2楼 ·

如果元素的数量很少,那么简单地在所有元素上循环应该没有问题:

import numpy as np

a = [['A', 'B'], ['B', 'B'], ['B', 'C'], ['C', 'B'], ['B', 'A'],
        ['A', 'D'], ['D', 'D'], ['D', 'A'] ['A', 'B'], ['B', 'A'], ['A', 'D']]                                                                                                                                      

a = np.asarray(a)                                                                                                                                   
elems = np.unique(a)                                                                                                                                
dim = len(elems)                                                                                                                                    
P = np.zeros((dim, dim))                                                                                                                            

for j, x_in in enumerate(elems):                                                                                                                    
    for k, x_out in enumerate(elems):                                                                                                               
        P[j,k] = (a == [x_in, x_out]).all(axis=1).sum()                                                                                             

    if P[j,:].sum() > 0:                                                                                                                            
        P[j,:] /= P[j,:].sum()

输出:

^{pr2}$

但是,您也可以使用带有预先分配的转换矩阵的计数器,将元素映射到索引,将计数指定为值,并规范化(最后两个步骤与我一样)。在

网友
3楼 ·
from collections import Counter

a = [['A', 'B'],
     ['B', 'B'],
     ['B', 'C'],
     ['C', 'B'],
     ['B', 'A'],
     ['A', 'D'],
     ['D', 'D'],
     ['D', 'A'],
     ['A', 'B'],
     ['B', 'A'],
     ['A', 'D']]

counts = Counter(map(tuple, a))

letters = 'ABCD'
p = []    

for letter in letters:
     d = sum(v for k, v in counts.items() if k[0] == letter)
     p.append([counts.get((letter, x), 0) / d  for x in letters])

print(p)

输出

^{pr2}$

相关问题