You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中计算数组在另一数组内出现次数的高效方法

高效统计小数组在大数组中出现次数的实现方案

针对大数组下纯Python循环性能过差的问题,可直接使用NumPy的向量化操作实现,全程无Python层循环,性能相比for循环提升可达千倍,且内存占用极低。

通用实现方案(支持任意数值类型数组)

核心利用numpy.lib.stride_tricks.as_strided创建滑动窗口视图,不会额外复制数组数据,适合超大规模数组处理。

import numpy as np
from numpy.lib.stride_tricks import as_strided

def count_occurrences(a: np.ndarray, b: np.ndarray) -> int:
    len_a = a.size
    len_b = b.size
    # 边界处理:小数组长度大于大数组直接返回0
    if len_b > len_a:
        return 0
    # 构造滑动窗口视图,无内存拷贝
    sliding_windows = as_strided(
        a,
        shape=(len_a - len_b + 1, len_b),
        strides=(a.strides[0], a.strides[0])
    )
    # 统计所有元素和b完全匹配的窗口数量
    return int((sliding_windows == b).all(axis=1).sum())

测试示例

a = np.array([1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1])
b = np.array([1, 1, 1])
print(count_occurrences(a, b))
# 输出结果为3,符合预期

二进制数组专属优化方案

如果你的数组固定为0/1组成的二进制数组,且小数组长度不超过64,可以通过将窗口内容转换为整数做等值对比,性能还能再提升30%以上:

def count_binary_occurrences(a: np.ndarray, b: np.ndarray) -> int:
    len_a = a.size
    len_b = b.size
    if len_b > len_a:
        return 0
    # 小数组长度超过64时回退到通用方案
    if len_b > 64:
        return count_occurrences(a, b)
    # 提前计算小数组对应的整数值
    weight = 2 ** np.arange(len_b - 1, -1, -1, dtype=np.uint64)
    b_val = (b * weight).sum()
    # 滑动窗口批量计算整数值后对比
    sliding_windows = as_strided(a, shape=(len_a - len_b + 1, len_b), strides=(a.strides[0], a.strides[0]))
    win_vals = (sliding_windows * weight).sum(axis=1)
    return int((win_vals == b_val).sum())

注意事项

  • as_strided不会自动做边界检查,需提前处理len_b > len_a的边界情况避免非法内存访问
  • 如果处理的是多维数组,可先调用.flatten()转为一维数组后再传入函数处理

内容的提问来源于stack exchange,提问作者rjaditya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:15:02