Skip to content

Numpy 库介绍

Numpy

NumPy 是一个功能强大的 Python 库,主要用于对多维数组执行计算。NumPy 这个词来源于两个单词-- NumericalPythonNumPy 提供了大量的库函数和操作,可以帮助程序员轻松地进行数值计算。在数据分析和机器学习领域被广泛使用。他有以下几个特点:

  1. Numpy 内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy 会自动做并行计算。
  2. Numpy 底层使用 C 语言编写,内部解除了 GIL(全局解释器锁),其对数组的操作速度不受 Python 解释器的限制,效率远高于纯 Python 代码。
  3. 实用的线性代数、傅里叶变换和随机数生成函数。

总而言之,他是一个非常高效的用于处理数值型运算的包。

安装:

通过 pip install numpy 即可安装,如果是 anaconda 环境,默认就安装好了

教程地址(官网):https://docs.scipy.org/doc/numpy/user/quickstart.html。

ndarray 介绍

NumPy provides an N-dimensional array type, the ndarray,
which describes a collection of “items” of the same type.

NumPy 提供了一个 N 维数组类型 ndarray,它描述了 相同类型 的“items”的集合。

用 ndarray 进行存储:

python
import numpy as np

# 创建 ndarray
score = np.array([
    [80, 89, 86, 67, 79],
    [78, 97, 89, 67, 81],
    [90, 94, 78, 67, 74],
    [91, 91, 90, 67, 69],
    [76, 87, 75, 67, 86],
    [70, 79, 84, 67, 84],
    [94, 92, 93, 67, 64],
    [86, 85, 83, 67, 80]]
)

提问:

使用 Python 列表可以存储一维数组,通过列表的嵌套可以实现多维数组,那么为什么还需要使用 Numpy 的 ndarray 呢?

性能对比

Numpy 数组和 Python 列表性能对比:

在这里我们通过一段代码运行来体会到 ndarray 的好处

python
import numpy as np
import time

# Python 列表的方式
t1 = time.time()
a = []
for x in range(1000000):
    a.append(x ** 2)
t2 = time.time()
t = t2 - t1
print('列表执行时间:', t)

花费的时间大约是 0.32 左右。而如果使用 numpy 的数组来做,那速度就要快很多了:

python
import time
import numpy as np

t3 = time.time()
b = np.arange(1000000) ** 2
t4 = time.time()
print('np 执行时间:', t4 - t3)

从中我们看到 ndarray 的计算速度要快很多,节约了时间。

机器学习的最大特点就是大量的数据运算,那么如果没有一个快速的解决方案,那可能现在 python 也在机器学习领域达不到好的效果。

ndarray 为什么可以这么快?

ndarray 的优势

内存块风格

ndarray 到底跟原生 python 列表有什么不同呢,请看一张图:

从图中我们可以看出 ndarray 在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。

这是因为 ndarray 中的所有元素的类型都是相同的,而 Python 列表中的元素类型是任意的,所以 ndarray 在存储元素时内存可以连续,而 python 原生 list 就只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面 Numpy 的 ndarray 不及 Python 原生 list,但在科学计算中,Numpy 的 ndarray 就可以省掉很多循环语句,代码使用方面比 Python 原生 list 简单的多。

矩阵运算

Numpy 支持常见的数组和矩阵操作。对于同样的数值计算任务,使用 Numpy 比直接使用 Python 要简洁的多。

多维数组

Numpy 使用 ndarray 对象来处理多维数组,该对象是一个快速而灵活的大数据容器。

小结

  • numpy 介绍【了解】
    • 一个开源的 Python 科学计算库
    • 计算起来要比 python 简洁高效
    • Numpy 使用 ndarray 对象来处理多维数组
  • ndarray 介绍【了解】
    • NumPy 提供了一个 N 维数组类型 ndarray,它描述了相同类型的 “items” 的集合。
    • 生成 numpy 对象: np.array()
  • ndarray 的优势【掌握】
    • 内存块风格
      • list -- 分离式存储,存储内容多样化
      • ndarray -- 一体式存储,存储类型必须一样
    • ndarray 支持并行化运算(向量化运算)
    • ndarray 底层是用 C 语言写的,效率更高,释放了 GIL

ndarray 的属性

数组属性反映了数组本身固有的信息。

属性名字属性解释
ndarray.shape数组维度的元组
ndarray.ndim数组维数
ndarray.size数组中的元素数量
ndarray.itemsize一个数组元素的长度(字节)
ndarray.dtype数组元素的类型

ndarray 的形状

shell
score.shape

就是数组有多少维度,每个维度有多少个元组。

(一维元素个数,二维元素个数,三维元素个数 .....)

ndarray 的类型

shell
type(score.dtype)

dtype 是 numpy.dtype 类型,先看看对于数组来说都有哪些类型

名称描述简写
np.bool用一个字节存储的布尔类型(True 或 False)'b'
np.int8一个字节大小,-128 至 127'i'
np.int16整数,-32768 至 32767'i2'
np.int32整数,-2^31 至 2^32 -1'i4'
np.int64整数,-2^63 至 2^63 - 1'i8'
np.uint8无符号整数,0 至 255'u'
np.uint16无符号整数,0 至 65535'u2'
np.uint32无符号整数,0 至 2^32 - 1'u4'
np.uint64无符号整数,0 至 2^64 - 1'u8'
np.float16半精度浮点数:16 位,正负号 1 位,指数 5 位,精度 10 位'f2'
np.float32单精度浮点数:32 位,正负号 1 位,指数 8 位,精度 23 位'f4'
np.float64双精度浮点数:64 位,正负号 1 位,指数 11 位,精度 52 位'f8'
np.complex64复数,分别用两个 32 位浮点数表示实部和虚部'c8'
np.complex128复数,分别用两个 64 位浮点数表示实部和虚部'c16'
np.object_python 对象'O'
np.string_字符串'S'
np.unicode_unicode 类型'U'

创建数组的时候指定类型

python
>>> a = np.array([[1, 2, 3],[4, 5, 6]], dtype=np.float32)
>>> a.dtype
dtype('float32')

>>> arr = np.array(['python', 'tensorflow', 'scikit-learn', 'numpy'], dtype=np.string_)
>>> arr
array([b'python', b'tensorflow', b'scikit-learn', b'numpy'], dtype='|S12')

基本操作

生成数组的方法

  • np.ones(shape, dtype)
  • np.ones_like(a, dtype)
  • np.zeros(shape, dtype)
  • np.zeros_like(a, dtype)

生成指定形状的列表数据

python
>>> ones = np.ones([4, 8])
>>> ones
array([[1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.],
       [1., 1., 1., 1., 1., 1., 1., 1.]])

生成指定维度的空白数据

python
>>> np.zeros_like(ones)
array([[0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0.]])

从现有数组生成

生成方式

  • np.array(object, dtype)
  • np.asarray(a, dtype)
python
import numpy as np

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

# 从现有的数组当中创建
arr1 = np.array(arr)

# 相当于索引的形式,并没有真正的创建一个新的
arr2 = np.asarray(arr1)

生成固定范围的数组

等差数组 — 指定数量

np.linspace (start, stop, num, endpoint)

参数:

  • start: 序列的起始值
  • stop: 序列的终止值
  • num: 要生成的等间隔样例数量,默认为 50
  • endpoint: 序列中是否包含 stop 值,默认为 ture
python
>>> # 生成等间隔的数组
>>> np.linspace(0, 100, 11)
array([0., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.])

等差数组 — 指定步长

np.arange(start,stop, step, dtype)

参数

  • step: 步长,默认值为 1
python
>>> np.arange(10, 50, 2)
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,
       44, 46, 48])

等比数列

参数:

  • num: 要生成的等比数列数量,默认为 50
python
>>> # 生成 10^x
>>> np.logspace(0, 2, 5)
array([1.           3.16227766  10.          31.6227766  100.])