【发布时间】:2021-09-24 08:38:53
【问题描述】:
假设一个 1 和 0 的序列 (np.array)。我需要构建二阶马尔可夫链。为此,我需要计算 T001,... T111 的比例,其中 T001 是序列出现 [0,0,1] 的次数。显然我可以做一个 for 循环,但我试图避免这种情况。理想情况下,该方法可以扩展到k-oder。
【问题讨论】:
标签: python python-3.x numpy
假设一个 1 和 0 的序列 (np.array)。我需要构建二阶马尔可夫链。为此,我需要计算 T001,... T111 的比例,其中 T001 是序列出现 [0,0,1] 的次数。显然我可以做一个 for 循环,但我试图避免这种情况。理想情况下,该方法可以扩展到k-oder。
【问题讨论】:
标签: python python-3.x numpy
任务可以分为两个子任务:首先是创建所有长度为 3 的子序列,然后计算所有唯一的子序列。这两项任务都可以通过内置的numpy 方法完成:
假设输入序列在a中存储为numpy数组,第一个点可以用
windows = np.lib.stride_tricks.sliding_window_view(a, 3)
然后我们可以使用计算不同的窗口
unique_windows, counts = np.unique(windows, axis=0, return_counts=True)
【讨论】:
您可以使用more_itertools.windowed 和collections.Counter 的组合:
from more_itertools import windowed
from collections import Counter
import numpy as np
np.random.seed(0)
a = np.random.choice([0,1], size=100)
Counter(windowed(a, n=3))
输入:
array([0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1,
1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1,
1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0,
0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1,
1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0])
输出:
Counter({(0, 1, 1): 14,
(1, 1, 0): 14,
(1, 0, 1): 15,
(1, 1, 1): 16,
(1, 0, 0): 10,
(0, 0, 1): 10,
(0, 1, 0): 12,
(0, 0, 0): 7})
使用自定义键:
{'T'+''.join(map(str, k)): v for k,v in Counter(windowed(a, n=3)).items()}
输出:
{'T011': 14,
'T110': 14,
'T101': 15,
'T111': 16,
'T100': 10,
'T001': 10,
'T010': 12,
'T000': 7}
from itertools import product
possible_keys = ['T'+''.join(map(str, k)) for k in product([0,1], repeat=3)]
输出:
['T000', 'T001', 'T010', 'T011', 'T100', 'T101', 'T110', 'T111']
你可以结合使用字典get方法:
## as comprehension
{k: out.get(k, 0) for k in possible_keys}
## as classical loop
for key in possible_keys:
out.get(key, 0) # default value is 0
from itertools import product
a = [0,1,1,0]
out = {'T'+''.join(map(str, k)): v for k,v in Counter(windowed(a, n=3)).items()}
possible_keys = ['T'+''.join(map(str, k)) for k in product([0,1], repeat=3)]
out = {k: out.get(k, 0) for k in possible_keys}
输出:
{'T000': 0,
'T001': 0,
'T010': 0,
'T011': 1,
'T100': 0,
'T101': 0,
'T110': 1,
'T111': 0}
from itertools import product
default = {'T'+''.join(map(str, k)): 0 for k in product([0,1], repeat=3)}
out = default | out # update default with the values in out
【讨论】:
from collections import defaultdict ; out = defaultdict(int, {'T'+''.join(map(str, k)): v for k,v in Counter(windowed(a, n=3)).items()}) ; out['Txxx']
{'p'+''.join(map(str, k[1:])): v for k,v in zip(d.keys(), np.array(list(d.values())) / sum(list(d.values())))}。好吧,理想情况下,由于顺序是 2(意味着一个序列中出现 3 次),我需要一个带有 Txxx 的 4x4 矩阵,然后我可以除以总和并得到比例。