转移概率矩阵

Wil*_*iam 1 python arrays matrix linear-algebra

我有以下数组:

a=[['A', 'B'],
 ['B', 'B'],
 ['B', 'C'],
 ['C', 'B'],
 ['B', 'A'],
 ['A', 'D'],
 ['D', 'D'],
 ['D', 'A'],
 ['A', 'B'],
 ['B', 'A'],
 ['A', 'D']]
Run Code Online (Sandbox Code Playgroud)

我希望制作一个转移概率矩阵,这样我得到:

[[P_AA,P_AB,P_AC,P_AD],
[P_BA,P_BB,P_BC,P_BD],
[P_CA,P_CB,P_CC,P_CD],
[P_DA,P_DB,P_DC,P_DD]]
Run Code Online (Sandbox Code Playgroud)

(以上用于说明),其中计算数组 a 等中有P_AA多少个除以。我已经开始使用计数器["A","A"]P_AA+P_AB+P_AC+P_AD

from collections import Counter
Counter(tuple(x) for x in l)
Run Code Online (Sandbox Code Playgroud)

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

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})
Run Code Online (Sandbox Code Playgroud)

所以矩阵应该是,

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

DYZ*_*DYZ 5

基于 pandas 的解决方案:

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
Run Code Online (Sandbox Code Playgroud)