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

为何np.zeros_like(x)与np.zeros(len(x))生成的数组结果不同?

np.zeros(len(x))与np.zeros_like(x)的结果差异解析

问题复现

使用np.zeros(len(x))时函数能得到正确浮点结果:

import numpy as np

def discount_cumsum(x: np.ndarray, d):
    # 该行代码可正常运行
    y = np.zeros(len(x))

    y[-1] = x[-1]
    for i in range(len(x) - 2, -1, -1):
        y[i] = x[i] + d * y[i + 1]
    return y

discount_cumsum(np.array(range(5)), 0.5) # array([1.625, 3.25 , 4.5  , 5.   , 4.   ])

切换为np.zeros_like(x)时得到错误的整数结果:

def discount_cumsum_2(x: np.ndarray, d):
    # 该行代码无法得到正确结果
    y = np.zeros_like(x)

    y[-1] = x[-1]
    for i in range(len(x) - 2, -1, -1):
        y[i] = x[i] + d * y[i + 1]
    return y

discount_cumsum_2(np.array(range(5)), 0.5) # array([1, 3, 4, 5, 4])

差异核心原因:数据类型不一致

两者的本质区别在于生成数组的数据类型:

  • np.zeros(len(x))默认生成float64类型的浮点数组,计算过程中带小数的中间结果能完整保留,最终输出正确的浮点结果。
  • np.zeros_like(x)会完全继承输入x的数据类型。这里传入的range(5)转为numpy数组后是int64整数类型,因此生成的y也是整数数组。计算时,所有带小数的结果会被自动截断取整(比如2.5直接转为2),最终得到错误的整数输出。

如果要让np.zeros_like生成浮点数组,只需显式指定数据类型:

y = np.zeros_like(x, dtype=np.float64)

正确实现参考

你最初的代码通过显式转换数据类型避免了这个问题,是更严谨的写法:

import numpy as np
from numba import njit

@njit
def discount_cumsum(x: np.ndarray, d):
    y = x.copy().astype(np.float32)
    for i in range(len(y) - 2, -1, -1):
        y[i] += d * y[i + 1]
    return y

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:46:08