统计01序列构建k阶马尔可夫链的无循环高效计数方法
k阶马尔可夫链模式统计的无循环实现方案
核心是用NumPy的向量化操作替代循环,支持任意阶数的0/1序列模式统计,适配2阶到高阶的需求。
通用实现代码
import numpy as np def count_markov_patterns(seq: np.ndarray, k: int) -> tuple[np.ndarray, np.ndarray]: """ 统计0/1序列中所有长度为k+1的连续模式的出现次数与占比 参数: seq: 一维np.ndarray,仅包含0/1元素 k: 马尔可夫链阶数 返回: counts: 数组,索引对应模式的二进制整数值,值为对应模式的出现次数 ratios: 数组,对应各模式的出现占比 """ # 生成所有长度为k+1的滑动窗口,无显式循环 windows = np.lib.stride_tricks.sliding_window_view(seq, window_shape=k+1) # 每个窗口转成唯一整数:二进制位对应窗口的0/1值 bits_weight = 2 ** np.arange(k, -1, -1) pattern_ids = (windows * bits_weight).sum(axis=1) # 统计所有可能模式的频次,自动补全出现次数为0的模式 counts = np.bincount(pattern_ids, minlength=2**(k+1)) # 计算占比 ratios = counts / counts.sum() return counts, ratios
2阶场景使用示例
如果需要统计T001到T111共8种模式的结果,直接传入k=2即可:
# 示例输入序列 seq = np.array([0,0,1,0,0,1,1,1,0,1,1,0]) counts, ratios = count_markov_patterns(seq, k=2) # 生成Txxx格式的模式名 pattern_names = [f"T{i:03b}" for i in range(8)] # 输出各模式对应结果 for name, cnt, rat in zip(pattern_names, counts, ratios): print(f"{name}: 次数{cnt}, 占比{rat:.2f}")
方案说明
- 全程无显式for循环,所有运算都是NumPy向量化实现,长序列下性能远高于循环写法
- 可以直接扩展到k阶马尔可夫的统计需求,只需要修改传入的
k参数即可,逻辑不需要改动 - 返回的
counts数组索引与模式一一对应:索引转成k+1位二进制字符串,加上前缀T就是你需要的Txxx命名,比如索引1对应二进制001,就是T001,和需求完全匹配
内容的提问来源于stack exchange,提问作者deblue
相关产品推荐
相关产品推荐

