为什么hstack()复制数据而hsplit()创建视图?
在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