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

scikit-learn KNN.predict报错ndarray is not C-contiguous

问题描述

调用预测函数实现评分预测功能时,编写初始代码如下:

def convert_to_df(obj):
    obj_dic = obj.dict()
    df = pd.DataFrame(obj_dic.values(), index=obj_dic.keys())
    df.reset_index(drop=True, inplace=True)
    return df


@app.get("/get_rating")
def get_rating(features: Features):
    features = convert_to_df(features).T # shape (1, 26)
    return {'rating': Predictor().predict(features)}

运行代码时触发如下报错:

File "stringsource", line 658, in View.MemoryView.memoryview_cwrapper File "stringsource", line 349, in View.MemoryView.memoryview.cinit ValueError: ndarray is not C-contiguous

代码中使用的Predictor是基于scikit-learn实现的KNN模型训练封装类,其predict方法初始实现如下:

def predict(self, features) -> int:
    return self.model.predict(features)
报错原因
  • 对DataFrame执行.T转置操作时,pandas不会重新分配连续内存,仅修改数组的步长规则,转置后底层numpy数组会变为Fortran(列优先)内存布局,不再满足C-contiguous(行优先连续内存)要求。
  • scikit-learn的KNN模型底层基于Cython实现,预测阶段强制要求输入数组为C-contiguous内存布局,直接传入转置后的DataFrame就会触发该值错误。
  • 初始的convert_to_df逻辑冗余,先构建竖表再转置的写法完全不必要,是触发内存布局问题的直接诱因。
修复方案

优先从根源避免不必要的转置操作,再做内存格式兼容即可解决问题:

  1. 优化convert_to_df逻辑,直接构造单行DataFrame,省略转置步骤
import pandas as pd
import numpy as np

def convert_to_df(obj):
    obj_dic = obj.dict()
    # 直接传入字典列表构造单行DataFrame,不需要额外转置
    return pd.DataFrame([obj_dic])
  1. 传入模型前统一将特征转换为C连续内存格式,既可以在接口层处理,也可以在Predictor的predict方法中做兼容,后者对所有调用场景生效,更稳妥:
  • 接口层调整示例:
@app.get("/get_rating")
def get_rating(features: Features):
    features_df = convert_to_df(features)
    # 转换为C连续数组再传入预测
    features_arr = np.ascontiguousarray(features_df.values)
    return {'rating': Predictor().predict(features_arr)}
  • Predictor层兼容示例:
import numpy as np

def predict(self, features) -> int:
    # 无论传入的是DataFrame还是非连续数组,都统一转换为C连续格式
    features = np.ascontiguousarray(features)
    return self.model.predict(features)

内容的提问来源于stack exchange,提问作者Tlaloc-ES

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 04:42:23