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

如何对Pandas Series执行滚动窗口按位与运算?

如何高效实现Pandas Rolling窗口的按位与运算?

问题背景

我有一个存储32位无符号整数的Pandas Series,需要计算每个rolling窗口内所有值的按位与结果。Pandas的rolling对象并没有提供直接的bitwise_and方法,尝试df.rolling(2).bitwise_and()会报错。目前通过自定义函数结合apply实现了需求,但实际场景中窗口大小在100-20000之间,且数据量较大,apply的效率无法满足需求,需要更高效的方案。

尝试过的无效代码:

import pandas as pd
import numpy as np

# 示例16位整数(实际为uint32)
df = pd.Series([0xFFFF, 0xFEAB, 0x0000, 0x1111, 0x5555, 0xAAAA], dtype='uint32')  
df.rolling(2).bitwise_and()  # Pandas无此方法,会报错

现有低效实现:

def accumulate_bitwise_and(values):
    result = np.uint32(0xFFFFFFFF)
    for v in values:
        # Pandas rolling窗口会自动转浮点,需要强制转回uint32
        result &= np.uint32(v)
    return result

# 窗口大小为2的示例
accum = df.rolling(2).apply(accumulate_bitwise_and)
accum.drop(accum.index[0], inplace=True)  # 移除初始NaN
accum = accum.astype("uint32")

高效解决方案:基于Numpy向量化操作

apply本质是逐窗口调用Python函数,窗口越大、数据量越大,循环开销越明显。我们可以利用Numpy的滑动窗口和向量化按位与操作,彻底避免Python层面的循环,大幅提升效率。

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

import pandas as pd
import numpy as np

# 示例数据
df = pd.Series([0xFFFF, 0xFEAB, 0x0000, 0x1111, 0x5555, 0xAAAA], dtype='uint32')
window_size = 2

# 转换为Numpy数组
arr = df.to_numpy()

# 创建滑动窗口视图(无额外内存拷贝)
windows = np.lib.stride_tricks.sliding_window_view(arr, window_size)

# 对每个窗口执行按位与归约
result = np.bitwise_and.reduce(windows, axis=1)

# 转换回Pandas Series,匹配原索引(跳过前window_size-1个位置)
accum = pd.Series(result, index=df.index[window_size-1:], dtype='uint32')

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

如果你的Numpy版本低于1.20,可以手动通过步幅构造滑动窗口:

def sliding_window(arr, window_size):
    # 计算滑动窗口的形状和步幅
    shape = (arr.size - window_size + 1, window_size)
    strides = (arr.strides[0], arr.strides[0])
    # 创建滑动窗口视图(无内存拷贝)
    return np.lib.stride_tricks.as_strided(arr, shape=shape, strides=strides)

# 后续步骤与方法1一致
arr = df.to_numpy()
windows = sliding_window(arr, window_size)
result = np.bitwise_and.reduce(windows, axis=1)
accum = pd.Series(result, index=df.index[window_size-1:], dtype='uint32')

方案优势

  • 效率极高:完全基于Numpy的C级向量化运算,避免了Python循环的开销,在大窗口、大数据量场景下,效率比apply高100-1000倍以上。
  • 无额外类型转换:直接操作uint32类型数组,不需要处理Pandas rolling窗口自动转浮点的问题。
  • 内存友好:滑动窗口视图不会拷贝原始数据,仅创建视图,内存占用远低于复制整个窗口数据的方案。

注意事项

当窗口大小极大(如20000)且数据量非常大时,滑动窗口视图会占用一定内存(内存占用为(数据量-窗口大小+1)*窗口大小*4字节),如果内存压力过大,可以考虑分块处理原始数据,逐块计算后合并结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 16:53:09