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

如何用向量化方式生成NumPy数组的多阶幂次数组?

当然有更高效的向量化方案!我们可以借助NumPy的广播机制或者累积乘积特性来替代显式循环,而且不同方法在不同场景下各有优势。先回顾下你的需求:

你有这样一个NumPy数组:

arr = np.array([[1, 2], [3, 4]])

想要生成一个包含该数组从0阶到指定order阶幂次的新数组,比如当order=3时,结果应该是:

arr_new = [[1, 1, 1, 2, 1, 4, 1, 8], [1, 1, 3, 4, 9, 16, 27, 64]]

你当前用for循环实现,但希望找到更快的向量化方法。


几种向量化实现方案

下面是三种高效的向量化方法,我们会结合基准测试来对比它们的性能:

1. 广播+Reshape 方案

利用NumPy的广播特性,直接让数组和幂次数组进行元素级运算,最后重塑成目标形状:

def broadcast_based_reshape(arr, order):
    # 创建幂次数组,通过广播匹配原数组维度
    powers = np.arange(order + 1)[:, None]
    # 计算各阶幂次,得到三维数组(行 × 幂次 × 列)
    exponentiated = arr[:, None] ** powers
    # 重塑为二维目标数组并返回
    return exponentiated.reshape(arr.shape[0], -1)

2. 广播+Hstack 方案

思路和上面类似,只是最后用np.hstack横向拼接各阶幂次的结果:

def broadcast_based_hstack(arr, order):
    # 创建三维幂次数组,触发广播机制
    powers = np.arange(order + 1)[:, None, None]
    # 计算各阶幂次
    exponentiated = arr ** powers
    # 横向拼接所有幂次结果
    return np.hstack(exponentiated)

3. 累积乘积(Cumprod) 方案

对于高阶幂次场景,累积乘积的方式可以避免重复计算幂次,性能提升更明显:

def broadcast_cumprod_reshape(arr, order):
    rows, cols = arr.shape
    # 预分配结果数组,中间维度存储0到order阶的幂次
    out = np.empty((rows, order + 1, cols), dtype=arr.dtype)
    # 0次幂恒为1
    out[:, 0, :] = 1
    # 将原数组广播到(行 × 阶数 × 列)的维度
    a = np.broadcast_to(arr[:, None], (rows, order, cols))
    # 通过累积乘积得到各阶幂次(从1阶开始)
    np.cumprod(a, axis=1, out=out[:,1:,:])
    # 重塑为二维目标数组
    return out.reshape(rows, -1)

基准测试对比

我们在两种典型场景下对比这些方法和你原来的循环实现:

  • 小型数组:arr = np.array([[1, 2], [3,4]]),order=3
  • 大型数组:arrLarge = np.random.randint(0, 10, (100, 100)),orderLarge=10

你的原循环实现代码:

def loop_based(arr, order):
    # 预分配结果数组
    rows, cols = arr.shape
    arr_new = np.zeros((rows, (order+1) * cols))
    # 遍历每个幂次,填充结果数组
    for i in range(order + 1):
        arr_new[:, (i * cols) : (i + 1) * cols] = arr**i
    return arr_new

测试结果

小型数组(2x2):
%timeit -n 100000 loop_based(arr, order)
# 7.41 µs ± 174 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit -n 100000 broadcast_based_hstack(arr, order)
# 10.1 µs ± 137 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit -n 100000 broadcast_based_reshape(arr, order)
# 3.31 µs ± 61.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
%timeit -n 100000 broadcast_cumprod_reshape(arr, order)
# 11 µs ± 102 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
大型数组(100x100):
%timeit -n 1000 loop_based(arrLarge, orderLarge)
# 261 µs ± 5.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit -n 1000 broadcast_based_hstack(arrLarge, orderLarge)
# 225 µs ± 4.15 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit -n 1000 broadcast_based_reshape(arrLarge, orderLarge)
# 223 µs ± 2.16 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit -n 1000 broadcast_cumprod_reshape(arrLarge, orderLarge)
# 157 µs ± 1.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

结论

  • 处理小型数组时,广播+Reshape的方法速度最快,比原循环实现快了一倍多;
  • 处理大型数组时,累积乘积(Cumprod)的方法扩展性最好,性能领先其他方案,因为它避免了重复计算高次幂,效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:15:08