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

Numpy新数组赋值后值异常,与原数组不符问题求助

Numpy数组重排时数值异常的原因分析

问题场景

编写了用于重排三维Numpy坐标数组的reorder函数,调用后返回的数组数值被异常修改;改用列表实现的reorder_by_lst函数则能保留原数组数值,仅需调整维度即可得到正确结果。

出错的Numpy实现代码

import numpy as np
def reorder(points):
    # reshaping array
    points = points.reshape((4, 2))
    # creating empty output array
    points_new = np.zeros((4, 1, 2), np.uint8)
    # summing the values
    add = points.sum(1)
    # find difference
    diff = np.diff(points, axis=1)
    # with the smaller sum will be first, the maximum will be last
    points_new[0] = points[np.argmin(add)]
    points_new[3] = points[np.argmax(add)]
    # the smaller difference will be the second, the max difference - the third
    points_new[1] = points[np.argmin(diff)]
    points_new[2] = points[np.argmax(diff)]
    return points_new

调用代码与异常结果

调用代码:

input_data = np.array([[[ 573,  148]], [[  25,  223]], [[ 153, 1023]], [[ 730,  863]]])
output_data = reorder(input_data)

得到的异常结果:

np.array([[[ 25, 223]], [[ 61, 148]], [[153, 255]], [[218,  95]]])

正确的列表实现代码

def reorder_by_lst(points):
    # reshaping array
    points = points.reshape((4, 2))
    # summing the values
    add = points.sum(1)
    # find difference
    diff = np.diff(points, axis=1)
    # with the smaller sum will be first, the maximum will be last
    a = points[np.argmin(add)]
    d = points[np.argmax(add)]
    # the smaller difference will be the second, the max difference - the third
    b = points[np.argmin(diff)]
    c = points[np.argmax(diff)]
    lst = [a, b, c, d]
    return np.array(lst)

调用后正确结果(仅需调整维度):

np.array([[  25,  223], [ 730,  863], [ 573,  148], [ 153, 1023]])

原因分析

问题根源在points_new = np.zeros((4, 1, 2), np.uint8)这一行:你指定了数组的 dtype 为uint8,这是8位无符号整数类型,取值范围仅为0-255。

输入坐标中存在大量超过255的数值(如573、730、1023等),当把这些数值赋值给uint8类型数组时,Numpy会自动对数值进行模256取余运算,导致数值被截断变形:

  • 573 % 256 = 61
  • 730 % 256 = 218
  • 1023 % 256 = 255
  • 863 % 256 = 95

这就是结果中出现异常数值的原因。而列表实现的版本中,最终返回的数组未指定dtype,Numpy会自动推断为合适的整数类型(如int64),因此不会出现数值截断。

修复方案

将points_new的dtype改为和输入数组一致的类型,或者显式指定足够大的整数类型:

# 与输入数组保持一致的类型
points_new = np.zeros((4, 1, 2), dtype=points.dtype)
# 或显式指定大整数类型
points_new = np.zeros((4, 1, 2), np.int32)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 23:53:20