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

为何np.split向已有数组赋值时会创建副本?

关于NumPy中np.split视图与副本的疑问

我是Python新手,正在学习视图(view)与副本(copy)的特性,若问题浅显还请见谅!以下示例中,我使用np.split()拆分数组x:

当将np.split结果赋值给新对象(如包含3个一维数组的列表x1,或三个独立一维数组x2、x3、x4)时,这些对象都是x的视图,符合预期:

import numpy as np

x = np.arange(1, 10)                        # 创建长度为9的数组
x1 = np.split(x, (3,6))                     # 将数组拆分为一个新对象(数组列表)
print(x1[0].base)                           # 列表中的每个数组都是视图

x2, x3, x4 = np.split(x, (3, 6))            # 将数组拆分为三个新对象
print(x2.base)                              # 这些对象是视图

但当我创建一个空的(3,3)数组x5,并将np.split结果赋值给x5的每一行时(我知道这操作无意义,只是想理解拆分机制),却创建了副本:

x5 = np.empty((3,3), dtype = np.int32)      # 创建未初始化数组
x5[0], x5[1], x5[2] = np.split(x, (3, 6))   # 将x拆分后赋值给x5的每一行
print(x5.base)                              # 该对象是副本

我原以为是x5的切片导致副本生成,但对x2、x3、x4进行切片赋值时,它们仍为视图:

x2[:], x3[:], x4[:] = np.split(x, (3, 6))   # 用索引将数组拆分后赋值给三个已有对象
print(x2.base)                              # 这些对象仍是视图

我在视图与副本或np.split的相关资料中未找到解释,请问我忽略了什么?


核心原因解析

这两种赋值操作的本质区别在于目标对象的内存是否独立于原数组:

  • np.split直接赋值给新变量:np.split返回的是原数组的切片视图,这些视图本身不存储数据,只是指向原数组x的内存区域。当你把它们赋值给x1、x2等变量时,变量只是保存了这些视图的引用,自然和原数组共享内存。
  • 赋值给x5的行切片:x5是独立创建的新数组,有自己的内存空间。执行x5[0] = np.split(...)时,本质是把视图中的数据拷贝到x5已分配好的内存位置里,相当于复制了一份原数组的数据到x5的内存中,所以x5和原数组完全独立,是副本。
  • 对x2[:]的切片赋值:x2本身已经是原数组的视图,x2[:]指向的是x2对应的原数组内存区域。这种赋值是直接修改视图指向的原数组数据,没有创建新内存空间,所以x2依然是原数组的视图。

简单总结:直接接收np.split返回值拿到的是原数组的"窗口"(视图);把视图数据写到独立数组的内存里会生成副本;对已有视图的切片赋值只是修改原数组数据,视图属性不变。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:45:39