NumPy 中文文档

version: 1.14.0

Built with Teadocs

NumPy数组的内部组织

# numpy数组的内部组织

了解一下在幕后如何处理numpy数组有助于更好地理解numpy。这一节将不太详细。那些希望了解全部细节的人请参阅特拉维斯·奥列芬特的书“NumPy指南”。

NumPy数组由两个主要组件组成:原始数组数据(从现在起称为数据缓冲区)和有关原始数组数据的信息。数据缓冲区通常被认为是C或Fortran中的数组,Fortran是一个连续的(固定的)内存块,包含固定大小的数据项。NumPy还包含一组重要的数据,这些数据描述如何解释数据缓冲区中的数据。这些额外信息(除其他外)包括:

  1. 基本数据元素的大小(以字节为单位)。
  2. 数据缓冲区内数据的开始(相对于数据缓冲区开始的偏移量)。
  3. 维度的数量和每个维度的大小。
  4. 每个维度的元素之间的分离(“跨步”)。这不一定是元素大小的倍数。
  5. 数据的字节顺序(可能不是本机字节顺序)。
  6. 缓冲区是否是只读的。
  7. 有关基本数据元素解释的信息(通过dtype对象)。基本数据元素可以非常简单,可以是int或Float,也可以是复合对象(例如,类似于结构的对象)、固定字符字段或Python对象指针。
  8. 将数组解释为C阶还是Fortran阶。

这种安排允许非常灵活地使用数组。它允许的一件事是简单地更改元数据以更改数组缓冲区的解释。更改数组的字节顺序是一个简单的更改,不涉及数据的重新排列。数组的形状可以非常容易地更改,而无需更改数据缓冲区中的任何内容或任何数据复制。

除其他外,可以创建一个新的数组元数据对象,该对象使用相同的数据缓冲区来创建该数据缓冲区的新视图,该视图对该缓冲区有不同的解释(例如,不同的形状、偏移量、字节顺序、步长等),但共享相同的数据字节。numpy中的许多操作就是这样做的,比如切片。其他操作(如转置)不会在数组中移动数据元素,而是更改有关形状和步长的信息,以便数组的索引发生更改,但数组中的数据不会移动。

通常,这些新版本的数组元数据-但相同的数据缓冲区-是数据缓冲区中的新“视图”。有一个不同的ndarray对象,但它使用相同的数据缓冲区。这就是为什么如果一个人真的想要创建一个新的独立的数据缓冲区副本,那么就必须通过使用.Copy()方法强制复制。

数组中的新视图意味着数据缓冲区增加时的对象引用计数。如果仍然存在原始数组对象的其他视图,则简单地取消原始数组对象并不会删除数据缓冲区。