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

如何用Numpy高效实现滑动中位数?替代列表推导式方案

用Numpy实现高效滑动中位数

当然可以用纯Numpy函数实现滑动中位数,而且效率远高于列表推导式循环调用np.median的方式。核心思路是利用Numpy的滑动窗口视图和向量化排序避免Python循环开销,以下是两种可行的实现方案:

方案1:使用内置滑动窗口视图(推荐,Numpy 1.20+)

利用np.lib.stride_tricks.sliding_window_view生成滑动窗口的内存视图(无需复制原数组),再对所有窗口批量排序后提取中位数:

import numpy as np

def sliding_median(arr, window):
    # 生成滑动窗口视图,共享原数组内存
    windows = np.lib.stride_tricks.sliding_window_view(arr, window_shape=window)
    # 对每个窗口沿轴1排序(向量化操作,效率远高于循环排序)
    sorted_windows = np.sort(windows, axis=1)
    # 计算中位数对应的索引
    mid_idx = window // 2
    # 区分奇偶窗口的中位数计算逻辑
    if window % 2 == 1:
        return sorted_windows[:, mid_idx]
    else:
        return (sorted_windows[:, mid_idx-1] + sorted_windows[:, mid_idx]) / 2.0

方案2:手动构造滑动窗口(兼容旧版Numpy)

如果你的Numpy版本低于1.20,可以用np.lib.stride_tricks.as_strided手动构造滑动窗口,原理和方案1一致:

import numpy as np

def sliding_median_old(arr, window):
    arr_len = len(arr)
    num_windows = arr_len - window + 1
    # 计算内存步长,确保窗口连续且共享原数组内存
    elem_size = arr.itemsize
    windows = np.lib.stride_tricks.as_strided(
        arr,
        shape=(num_windows, window),
        strides=(elem_size, elem_size)
    )
    sorted_windows = np.sort(windows, axis=1)
    mid_idx = window // 2
    if window % 2 == 1:
        return sorted_windows[:, mid_idx]
    else:
        return (sorted_windows[:, mid_idx-1] + sorted_windows[:, mid_idx]) / 2.0

效率对比说明

原列表推导式方案每次循环都要单独调用np.median,而np.median内部会重复执行排序操作;上述方案通过批量排序所有滑动窗口,彻底避免了Python循环的开销,同时滑动窗口视图无需复制原数组内存,内存效率也更高。

测试示例

# 测试代码
arr = np.array([1,3,5,7,9,2,4,6,8])
window = 3
print(sliding_median(arr, window))
# 输出: [3. 5. 7. 7. 5. 4. 6.]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:00:48