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

xnx*_*xnx 6 python numpy

在 NumPy 中,为什么hstack()要从正在堆叠的数组中复制数据:

A, B = np.array([1,2]), np.array([3,4])
C = np.hstack((A,B))
A[0]=99
Run Code Online (Sandbox Code Playgroud)

C

array([1, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)

hsplit()创建数据视图

a = np.array(((1,2),(3,4)))
b, c = np.hsplit(a,2)
a[0][0]=99
Run Code Online (Sandbox Code Playgroud)

b

array([[99],
       [ 3]])
Run Code Online (Sandbox Code Playgroud)

我的意思是 - 实现这种行为背后的原因是什么(我发现不一致且难以记住):我接受这种情况发生,因为它是这样编码的......

Jos*_*del 6

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

基本的 C 实现在这里,并且有一个很好的讨论:

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


nne*_*neo 5

NumPy的一般试图创建视图只要有可能,因为内存拷贝是低效的,并且可以很快吃了很多次的。

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

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