为什么hstack()复制数据但是hsplit()会在其上创建一个视图?

时间:2014-03-24 17:31:16

标签: python numpy

在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 个答案:

答案 0 :(得分:4)

NumPy通常会尝试在可能的情况下创建视图 ,因为内存副本效率低下并且可能会很快耗尽很多周期。

hsplit将输入数组拆分为多个输出数组。输出数组都可以是原始父数组的一部分视图(因为它们基本上是简单的切片)。因此,为了提高效率,NumPy创建视图而不是副本。

hstack将两个完全独立的数组合并为一个输出数组。底层数组实现无法在单个数组中处理两个单独的数据源,因此无法与原始数据共享数据。因此,NumPy被迫创建副本。

答案 1 :(得分:4)

基本上,底层的ndarray数据结构只有一个指向其数据内存开头的指针,然后传递有关如何在每个维度中移动的信息。如果连接两个数组,它将不知道如何从一个内存位置移动到另一个内存位置。另一方面,如果将数组拆分为两个数组,则每个数组都可以轻松存储指向第一个元素的指针(位于原始数组中的某个位置)。

基本的C实现是here,并且在以下方面进行了很好的讨论:

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