numpy简介
NumPy数组概念
import numpy as np
NumPy: Numerical Python 的简称。
在Python中,类型是动态推断的。这意味着可以将任何类型的数据指定给任何变量:
# Python 代码 x = 4 x = "four"
/* C代码 */ int x = 4; x = "four"; // 编译失败
但是这种类型灵活性也指出了一个事实:Python 变量不仅是它们的值,还包括了关于值的类型的一些额外信息。
例如,当我们在Python中定义一个整型,例如x=10000 时,x 并不是一个“原生”整型,而是一个指针,指向一C语言的复合结构体,结构体里包含了一些值:
两者的异常在于,C语言整型本质上是对应某个内存位置的标签,里面存储的字节会编码成整型。而Python的整型其实是一个指针,指向包含这个Python对象所有信息的某个内存位置,其中包括可以转换成整型的字节。由于Python的整型结构体里面还包含了大量额外的信息,所以Python可以自由、动态地编码。但是,Python类型中的这些额外信息也会成为负担,在多个对象组合的结构体中尤其明显。
在某些方面,NumPy数组与Python内置的列表类型非常相似。但是随着数组在维度上变大,NumPy数组提供了更加高效的存储和数据操作。NumPy数组几乎是整个Python数据科学工具生态系统的核心。
Python提供了几种将数组存储在有效的、固定类型的数据缓存中的选项。如标准库的array模块,但更实用的是NumPy中的
ndarray
对象。
Python列表“不仅仅是一个列表”:
因为Python的动态类型特性,甚至可以创建一个异构的列表:
>>> L3 = [True, "2", 3.0, 4] >>> [type(item) for item in L3] [bool, str, float, int]
动态类型的列表和固定类型的(Numpy式)数组间的区别:
- 在实现层面,数组基本上包含一个指向连续数据块的指针;
- 另一方面,Python列表包含一个指向指针块的指针,这其中的每一个指针对应一个完整的Python对象(如前面看到的Python整型);
- 另外,列表的优势是灵活,因为每个列表元素是一个包含数据和类型信息的完整结构体,而且列表可以用任意类型的数据填充。固定类型的Numpy式数组缺乏这种灵活性,但是能更有效地存储和操作数据。
可以将图像(尤其是数字图像)简单地看作二维数字数组,这些数字数组代表各区域的像素值;声音片段可以看作时间和强度的一维数组;文本也可以通过各种方式转换成数值表示,一种可能的转换是用二进制数表示特定单词或单词对出现的频率。
请记住,不同于Python 列表,NumPy 要求数组必须包含同一类型的数据。如果类型不匹配,NumPy 将会向上转换(如果可行):
示例 | 说明 |
---|---|
![]() | 整型在这里被转换为浮点型 |
![]() | 如果希望明确设置数组的数据类型,可以用dtype 关键字 |
![]() | 内层的列表被当作二维数组的行 |
NumPy标准数据类型
当构建一个数组时,可以用一个字符串参数来指定数据类型
np.zeros(10, dtype='int16')
或者用相关的NumPy对象来指定
np.zeros(10, dtype=np.int16)
NumPy数组的属性
- 维度(
ndim
):数组的维度 - 形状(
shape
):数组每个维度的大小,返回值总为元组类型 - 大小(
size
):数组的总大小 - 数据类型(
dtype
):数组的数据类型 - 其他的属性有:表示每个数组元素字节大小的
itemsize
,以及表示数组总字节大小的属性nbytes
。一般来说,可以认为$nbytes=itemsize \times size$