能否在Pandas中对Motelling信号平滑方法进行向量化实现?
向量化实现Motelling信号平滑方法
当然可以实现向量化的Motelling函数应用!不过因为这个响应规则依赖前一时刻的输出值(属于带状态的递推逻辑),直接用普通的元素级向量化操作会有点棘手,但我们有几种高效的方式能避开逐行循环,提升处理速度。
方法1:用Numba实现编译后的递推(首推,适配大规模数据)
Numba能把Python循环编译成机器码,效率直逼原生向量化操作,还能完美处理这种带状态的逻辑。写个简单函数加个装饰器就行:
import numba import pandas as pd import numpy as np @numba.jit(nopython=True) def motelling_numba(signal): n = len(signal) output = np.zeros(n, dtype=np.int8) for i in range(n): if i == 0: # 初始时刻无前置输出,按规则直接判断 if signal[i] == 1: output[i] = -1 elif signal[i] == 5: output[i] = 1 else: output[i] = 0 else: prev_out = output[i-1] if signal[i] == 1 or (signal[i] == 2 and prev_out == -1): output[i] = -1 elif signal[i] == 5 or (signal[i] == 4 and prev_out == 1): output[i] = 1 else: output[i] = 0 return output # 假设你的DataFrame是df,信号列名为'S' df['F'] = motelling_numba(df['S'].values)
这个方法看起来是循环,但Numba编译后会以接近向量化的速度运行,比纯Python循环快几个数量级,非常适合处理大规模时间序列。
方法2:纯Pandas累积操作(适配小规模数据)
如果不想额外引入Numba,用Pandas自带的累积操作也能搞定。不过这种方法本质还是逐行处理,数据量大了速度会跟不上,适合小规模数据集:
def motelling_state(prev_state, current_s): prev_out = prev_state if current_s == 1 or (current_s == 2 and prev_out == -1): return -1 elif current_s == 5 or (current_s == 4 and prev_out == 1): return 1 else: return 0 # 初始化第一个输出值 first_val = -1 if df['S'].iloc[0] == 1 else 1 if df['S'].iloc[0] == 5 else 0 # 累积应用状态函数生成后续值 df['F'] = [first_val] for s in df['S'].iloc[1:]: df['F'].append(motelling_state(df['F'].iloc[-1], s))
方法3:向量化条件+循环(折中方案,适配中等规模数据)
要是你想尽量用向量化的条件判断,也可以结合前一时刻的输出值做批量判断,虽然还是要按顺序循环,但比纯Python循环效率高一些:
df['F'] = 0 # 初始化第一个值 df.loc[0, 'F'] = -1 if df['S'].iloc[0] == 1 else 1 if df['S'].iloc[0] == 5 else 0 # 按顺序更新后续行 for i in range(1, len(df)): prev_f = df['F'].iloc[i-1] # 用向量化条件判断当前行的输出 is_neg = (df['S'].iloc[i] == 1) | ((df['S'].iloc[i] == 2) & (prev_f == -1)) is_pos = (df['S'].iloc[i] == 5) | ((df['S'].iloc[i] == 4) & (prev_f == 1)) if is_neg: df.loc[i, 'F'] = -1 elif is_pos: df.loc[i, 'F'] = 1 else: df.loc[i, 'F'] = 0
最后总结下选择建议:
- 大规模时间序列:首推Numba编译的方法,代码简洁还跑得快;
- 纯Pandas生态下的小规模数据:用累积操作方法就行;
- 中等规模数据:试试向量化条件+循环的折中方案。
内容的提问来源于stack exchange,提问作者feetwet
相关产品推荐
相关产品推荐

