用pandas计算BTC交易数据滚动斜率触发Polyfit秩警告如何解决
警告产生原因
np.polyfit抛出的RankWarning本质是最小二乘拟合过程中输入的系数矩阵秩不足,拟合结果存在数值不稳定的问题,结合你的代码具体触发原因有两个:
- x轴取值设计错误:你使用
dt.datetime.toordinal把时间转成了按天计数的序数,同一自然日的所有分钟级数据的date_ordinal值完全相同。30分钟的窗口大概率落在同一天内,x轴输入的30个值全部相等,无法构造有效拟合的系数矩阵,直接触发秩警告。 - 边界样本窗口长度不足:循环从索引0开始执行时,当
index < time_period,切片得到的样本量小于30,甚至只有1~2个样本,样本量不足也会导致拟合矩阵病态。
解决方法
按优先级从高到低选择对应方案即可:
- 替换x轴取值为窗口内序号:完全不需要引入时间值作为x轴,直接用窗口内的样本位置作为x输入,天然保证x值均匀递增无重复,修改拟合代码如下:
# 窗口内第1个点x=0,第2个x=1,...第31个x=30,完全避免x值重复问题 price_slope = np.polyfit(np.arange(time_period + 1), result['Close'][index-time_period:index+1], 1) - 调整循环起始索引:跳过样本量不足的前N条数据,避免边界拟合错误:
# 从索引等于time_period开始循环,保证每个窗口刚好有31个样本 for index in range(time_period, len(result)): price_slope = np.polyfit(np.arange(time_period + 1), result['Close'][index-time_period:index+1], 1) - 优化计算逻辑提升效率:不用手动写循环迭代,直接用pandas的滚动计算接口,代码更简洁运行效率更高:
def calc_slope(window): # 返回拟合得到的斜率值 return np.polyfit(np.arange(len(window)), window, 1)[0] time_period = 30 # 不足窗口长度的位置自动返回NaN,无需额外处理边界 result['price_slope'] = result['Close'].rolling(window=time_period + 1).apply(calc_slope) - 如果确实需要保留时间作为拟合x轴,把时间转成毫秒/秒级时间戳即可,不要使用按天的序数:
# 转成秒级时间戳,每个分钟数据的时间戳值唯一且递增 result['timestamp'] = pd.to_datetime(result['Open Time']).astype('int64') // 10**9
内容的提问来源于stack exchange,提问作者Jodhvir Singh
相关产品推荐
相关产品推荐

