Python numpy多维数组实现原理详解

1. 介绍numpy多维数组

numpy是Python中科学计算的重要库之一,它提供了一个高效的、方便的多维数组操作接口。numpy数组是一种类似list、tuple之类的Python数据结构,但是numpy数组可以存储同种数据类型的元素,这意味着在运算过程中不需要进行类型转换,从而提高了运算速度和效率。

1.1 numpy数组的创建

numpy数组可以经由以下几种方式创建:

使用numpy.array()函数进行数组创建

使用numpy.zeros()函数创建数组,并以0填充所有位置

使用numpy.ones()函数创建数组,并以1填充所有位置

使用numpy.random()函数创建随机数组

下面我们来看一下使用numpy.array()函数进行数组创建:

import numpy as np

array1 = np.array([1,2,3,4,5])

print("array1的类型为:", type(array1))

print("array1的元素类型为:", array1.dtype)

print("array1的大小为:", array1.shape)

这次我们创建了一个1维数组,并通过使用type()函数和. dtype属性检查了数组的类型和元素类型,最后使用. shape属性查看了数组的大小。以上代码的输出如下:

array1的类型为:<class 'numpy.ndarray'>

array1的元素类型为: int64

array1的大小为: (5,)

我们可以发现,.shape返回的元组表示数组的维度,其中第一个元素是数组的长度或者元素数量。

1.2 numpy数组的操作

numpy数组的操作包括对数组的形状、大小、类型、元素等的操作。比如我们可以对numpy数组进行如下的操作:

改变数组的形状

获取数组的元素

对数组的元素进行修改

对数组进行切片和索引

对数组进行合并、分割、堆叠

下面我们来分别看一下这些操作的实现方式。

1.2.1 改变数组的形状

首先,我们可以使用.reshape()函数改变numpy数组的形状,比如将一维数组转换为二维数组或更高维数组。

import numpy as np

array1 = np.array([1,2,3,4,5,6,7,8,9,10])

array2 = array1.reshape((2,5))

print(array2)

以上代码将array1转换成2x5的数组,输出结果如下:

[[ 1  2  3  4  5]

[ 6 7 8 9 10]]

1.2.2 获取和修改数组的元素

我们可以通过索引方式获取数组元素,例如以下代码:

import numpy as np

array1 = np.array([1,2,3,4,5,6,7,8,9,10])

print(array1[1])

以上代码输出为2,表示我们获得了数组array1中第2个元素。

我们还可以通过赋值方式来修改数组中的元素:

import numpy as np

array1 = np.array([1,2,3,4,5,6,7,8,9,10])

array1[0] = 0

print(array1)

这个例子中,我们修改了数组中的第一个元素为0。输出结果如下:

[ 0  2  3  4  5  6  7  8  9 10]

1.2.3 对数组进行切片和索引

对于多维数组,我们可以使用索引方式获取元素,以下代码实现了对2x5数组array2的索引:

import numpy as np

array1 = np.array([1,2,3,4,5,6,7,8,9,10])

array2 = array1.reshape((2,5))

print(array2[0][1])

以上代码输出为2,表示我们获得了数组array2中第1行第2个元素。

numpy数组还支持切片操作,以下代码展示如何对多维数组进行切片:

import numpy as np

array1 = np.array([1,2,3,4,5,6,7,8,9,10])

array2 = array1.reshape((2,5))

print(array2[:2,:3])

以上代码将返回一个2x3的数组,表示我们切出了原数组的前两行前三列。

1.2.4 对数组进行合并、分割、堆叠

numpy支持的合并、分割、堆叠操作包括:

np.concatenate(): 合并多个数组

np.split(): 分割数组

np.vstack(): 垂直堆叠数组

np.hstack(): 水平堆叠数组

下面的例子将展示如何使用np.concatenate()和np.vstack()函数:

import numpy as np

a = np.array([[1, 2], [3, 4]])

b = np.array([[5, 6]])

c = np.concatenate((a, b), axis=0)

print(c)

d = np.vstack((a, b))

print(d)

以上代码将返回一个3x2的数组,表示我们将数组a和数组b按行合并,并垂直将其叠在一起。

2. numpy多维数组实现原理

numpy的多维数组是通过C语言实现的,因此在运行时数组数据是在内存中以连续块的形式存储的。numpy数组还提供了一些特殊的数据类型,例如:numpy.bool、numpy.int32、numpy.float64等,这些数据类型在内存中的存储方式是不同的,具体可以参考npyArray结构体实现原理。

numpy多维数组的存储方式可以通过以下代码来查看:

import numpy as np

x = np.array([1,2,3,4,5])

print("x 内存地址:", x.data.ptr)

print("第1个元素内存地址:", x[0].data.ptr)

以上代码输出结果如下:

x 内存地址: 2404226422320

第1个元素内存地址: 2404226422320

通过.data.ptr属性可以获取numpy数组在内存中的地址。对于多维数组,numpy会依次在内存中存储各个元素。numpy还支持将多维数组存储为二进制文件,可以通过以下代码实现:

import numpy as np

a = np.arange(10).reshape(2, 5)

np.save("a.npy", a) # 保存为npy二进制文件

b = np.load("a.npy") # 读取npy二进制文件

print(b)

以上代码将会输出数组a的值,它会在磁盘上生成一个npy文件,供其他程序读取和处理。

3. 总结

在本文中,我们从numpy数组的创建、操作和实现原理三个方面介绍了numpy多维数组的使用方法。numpy数组是在C语言的基础上实现的,数组数据是以连续块的形式存储在内存中,因此numpy的操作效率较高。在实践中,我们可以使用numpy数组方便地进行各种数学计算和数据处理。

后端开发标签