本文最后更新于 320 天前,其中的信息可能已经过时,如有错误请发送邮件到wuxianglongblog@163.com
数组基础
数组(Array)是NumPy中的核心类型。整个NumPy模块都是围绕数组来构建的。
数组的引入
import numpy as np
数组的全称是N维数组(N-dimensional Array,ndarray),它是一个固定大小和形状的多维容器。
构造一个数组:
a = np.array([1, 2, 3, 4])
a
array([1, 2, 3, 4])
np.array((1, 2, 3, 4))
array([1, 2, 3, 4])
构造一个大小为2×3的二维数组:
np.array([[1, 2, 3], [4, 5, 6]])
array([[1, 2, 3],
[4, 5, 6]])
列表不支持直接用加法将每个元素都加1的操作:
b = [1, 2, 3, 4]
b + 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [7], in ()
----> 1 b + 1
TypeError: can only concatenate list (not "int") to list |
但是数组可以:
a + 1
array([2, 3, 4, 5])
数组的加法和乘法与列表不一样:
a + a
array([2, 4, 6, 8])
a * 2
array([2, 4, 6, 8])
a * a
array([ 1, 4, 9, 16])
a / a
array([1., 1., 1., 1.])
a
array([1, 2, 3, 4])
数组的属性
数组有一些基础属性,例如形状:
a.shape
(4,)
也可以用函数np.shape()
获取:
np.shape(a)
(4,)
该函数会将输入先转换为数组,因此还可以作用在非数组上:
np.shape([1, 2, 3, 4])
(4,)
多维列表的形状:
np.shape([[1, 2, 3], [4, 5, 6]])
(2, 3)
数组有类型的概念,数组中的元素属于同一个类型:
a.dtype
dtype('int64')
每个元素所占的字节数:
a.itemsize
8
数组中的元素总数:
a.size
4
数组使用一段连续的内存存储数据,数组所有元素所占空间:
a.nbytes
32
属性.nbytes
的值是这段连续内存的大小,等于属性.itemsize
和属性.size
的乘积。事实上,数组所占的存储空间要比这个数字大,因为数组还需要额外的空间存储数组的形状和数据类型信息。
查看数组维度:
a.ndim
1
数组的类型
数组的类型在产生数组时确定:
a
array([1, 2, 3, 4])
a.dtype
dtype('int64')
浮点数的类型默认是64位浮点数:
b = np.array([1.2, 3.5, 5.1])
b.dtype
dtype('float64')
当传入数据中有多种类型时,NumPy会自动进行判断,将数组转换为最通用的类型:
c = np.array([1 + 2j, 4.5, 3])
c.dtype
dtype('complex128')
更复杂的输入类型组合,NumPy会将它们转化为最基本的类型:object:
np.array(['abc', 1, {1, 2, 3}])
array(['abc', 1, {1, 2, 3}], dtype=object)
可以在定义数组的时候,指定dtype:
a = np.array([1, 2, 3, 4], dtype=float)
a.dtype
dtype('float64')
dtype可以接受多种类型的参数:
- Python中的类型名如:int、float、complex、str等。
- NumPy中的类型名:np.float32、np.int64、np.uint等。
- 类型名对应的字符串,如:"int"、"float"、"float32"、"int64"、"str"等。
数组的类型还可以转换:
np.asarray(a, dtype=int)
array([1, 2, 3, 4])
a.astype(int)
array([1, 2, 3, 4])
原数组不会变化:
a
array([1., 2., 3., 4.])
NumPy中的特殊值
np.array([1, -1, 0]) / 0
/var/folders/jy/yvmv88r909s2y0qzjw2ryn7m0000gn/T/ipykernel_20111/2604490398.py:1: RuntimeWarning: divide by zero encountered in true_divide
np.array([1, -1, 0]) / 0
/var/folders/jy/yvmv88r909s2y0qzjw2ryn7m0000gn/T/ipykernel_20111/2604490398.py:1: RuntimeWarning: invalid value encountered in true_divide
np.array([1, -1, 0]) / 0
array([ inf, -inf, nan])
数组的生成
全0数组和全1数组:
np.zeros(10)
array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
np.zeros((2, 3))
array([[0., 0., 0.],
[0., 0., 0.]])
np.ones((2, 3))
array([[1., 1., 1.],
[1., 1., 1.]])
np.ones(10)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
指定间距的等距数组:
np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
np.arange(5.0)
array([0., 1., 2., 3., 4.])
np.arange(0, 1, 0.1)
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
指定大小的等距数组:
np.linspace(1, 20, 10)
array([ 1. , 3.11111111, 5.22222222, 7.33333333, 9.44444444,
11.55555556, 13.66666667, 15.77777778, 17.88888889, 20. ])
数组的索引
一维数组的单元素索引:
a
array([1., 2., 3., 4.])
a[0]
1.0
a[0] = 10
a
array([10., 2., 3., 4.])
切片:
a[1:-1]
array([2., 3.])
a[::-1]
array([ 4., 3., 2., 10.])
多维数组的索引:
b = np.array([[ 1, 2, 3, 4, 5],
[11, 12, 13, 14, 15],
[21, 22, 23, 24, 25],
[31, 32, 33, 34, 35],
[41, 42, 43, 44, 45],
[51, 52, 53, 54, 55]])
b.shape
(6, 5)
b[0][1]
2
b[0, 1]
2
b[-1, -1]
55
索引某一行或某一列:
b[:, 1]
array([ 2, 12, 22, 32, 42, 52])
b[1]
array([11, 12, 13, 14, 15])
b[1, :]
array([11, 12, 13, 14, 15])
索引其中的某几行和某几列,例如,第二三行的第三四列:
b[1:3, 2:4]
array([[13, 14],
[23, 24]])
数组的迭代
a = np.arange(5)
for i in a:
print(i)
0
1
2
3
4
b = np.arange(24)
b.shape = 4, 6
b
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23]])
for i in b:
print(i)
[0 1 2 3 4 5]
[ 6 7 8 9 10 11]
[12 13 14 15 16 17]
[18 19 20 21 22 23]
for idx, v in np.ndenumerate(b):
print(idx, v)
(0, 0) 0
(0, 1) 1
(0, 2) 2
(0, 3) 3
(0, 4) 4
(0, 5) 5
(1, 0) 6
(1, 1) 7
(1, 2) 8
(1, 3) 9
(1, 4) 10
(1, 5) 11
(2, 0) 12
(2, 1) 13
(2, 2) 14
(2, 3) 15
(2, 4) 16
(2, 5) 17
(3, 0) 18
(3, 1) 19
(3, 2) 20
(3, 3) 21
(3, 4) 22
(3, 5) 23