Polars Series调用PyWavelet低通滤波函数报错的解决方法
在Polars中调用PyWavelet低通滤波函数时出现"buffer source array is read only"错误的解决方法
错误原因
- Polars列的底层数据是只读的numpy数组/内存视图,而PyWavelet的
pywt.threshold函数在处理过程中会尝试修改输入数组,触发只读缓冲区的权限错误。 - 原代码用
pl.struct('close').map(...)传递参数,实际传递的是struct对象而非纯数值数组,不符合lowpassfilter函数的参数预期。
正确调用方式
1. 修改滤波函数,适配Polars的只读数据特性
先将输入信号转换为可写的numpy数组,同时把生成器改为列表(避免迭代器赋值的潜在问题):
import pywt import numpy as np def lowpassfilter(signal, thresh = 0.63, wavelet="db4"): # 转换为可写数组,解决只读缓冲区问题 signal = np.array(signal, copy=True) thresh = thresh * np.nanmax(signal) coeff = pywt.wavedec(signal, wavelet, mode="per") # 用列表推导式替代生成器,确保系数被正确赋值 coeff[1:] = [pywt.threshold(i, value=thresh, mode="soft") for i in coeff[1:]] reconstructed_signal = pywt.waverec(coeff, wavelet, mode="per") return reconstructed_signal
2. 调整Polars的调用代码
使用pl.col指定目标列,并用map_elements替代map(map_elements专门用于对单列的完整数据应用函数):
df = df.with_columns( pl.col('close').map_elements(lowpassfilter).alias('wavelet') )
补充说明
如果close列包含缺失值,np.nanmax可以正常处理;若需要更高性能,可考虑将函数改为Polars的向量化UDF,但对于小波滤波这类需要完整序列的操作,map_elements是最直接的实现方式。
内容的提问来源于stack exchange,提问作者tone
相关产品推荐
相关产品推荐

