为什么hstack()复制数据而hsplit()创建视图?

6 投票
2 回答
871 浏览
提问于 2025-04-17 23:41

在NumPy中,为什么hstack()会复制被堆叠数组的数据呢:

A, B = np.array([1,2]), np.array([3,4])
C = np.hstack((A,B))
A[0]=99

对于C来说,结果是:

array([1, 2, 3, 4])

hsplit()则是创建了数据的一个视图

a = np.array(((1,2),(3,4)))
b, c = np.hsplit(a,2)
a[0][0]=99

对于b来说,结果是:

array([[99],
       [ 3]])

我的意思是——这种行为的实现背后有什么原因呢(我觉得这不太一致,也很难记住):我明白这是因为这样编写的代码...

2 个回答

5

NumPy通常会尽量创建视图,只要有可能,因为复制内存会很低效,而且会很快消耗很多计算资源。

hsplit这个函数会把输入的数组分成多个输出数组。输出的数组其实可以看作是原始数组的一部分(因为它们基本上就是简单的切片)。所以为了提高效率,NumPy选择创建视图,而不是复制数据。

hstack则是把两个完全独立的数组合并成一个输出数组。因为底层的数组实现不能在一个数组中处理两个不同的数据源,所以无法与原始数据共享。因此,NumPy不得不创建一个复制。

6

简单来说,ndarray这个数据结构底层只保存了一个指向数据内存开始位置的指针,还有一些关于如何在每个维度中移动的信息。如果你把两个数组拼接在一起,它就不知道该怎么从一个内存位置跳到另一个内存位置。相反,如果你把一个数组分成两个数组,每个数组都可以轻松地保存一个指向第一个元素的指针(这个元素在原始数组的某个地方)。

基本的C语言实现可以在这里找到,还有一个很好的讨论在:

http://scipy-lectures.github.io/advanced/advanced_numpy/index.html#life-of-ndarray

撰写回答