NumPy是一个功能强大的Python库,用于对向量和矩阵进行计算。它提供了大量的库函数,可以帮助程序员轻松地进行数值运算。它是一个运算速度非常快的数学库,它的许多底层函数是用C语言编写的。
广泛应用于以下领域:
- 机器学习
- 图像处理与计算机图形学
- 数学
- 数据分析、数据挖掘
1. NumPy的安装
安装方法:
使用pip安装。在Windows系统中的cmd里,输入以下命令:pip install numpy
。
2. Numpy的数组
NumPy的核心即是对数组进行运算。数组在这里称之为ndarray。NumPy数组可以看成是一个相同类型的数值组成的格网。数组的维数(dimensions)称为数组的秩(rank)。数组的形状(shape)是一个包含各维大小的元组。
2.1 定义数组
array()函数:
创建数组最基本的方法是array()函数,可以给它传递任意序列。
numpy.array(object, [dtype=None, copy=True, order='K', subok=False, ndmin=0])
创建一个新的数组。
关于order参数的详细说明:
order参数的'C'和'F'是NumPy中数组元素存储区域的两种排列格式,即C语言格式和Fortran语言格式。
创建一个3×3的2维数组:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32)
数组a在数据存储区域(内存中)中的存储方式(默认order="C",其中一个格子是4bytes):
|1|2|3|4|5|6|7|8|9|
在C语言中当第一维数组也就是第0轴的下标增加1时,元素在内存中的地址增加3个元素的字节数,在此例中也就是12bytes,从1的地址增加12bytes到4的地址。
若以F order创建数组:
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.float32, order="F")
数组b在内存中的数据存储区域中的存储方式:
|1|4|7|2|5|8|3|6|9|
在Fortran语言中,第一维也就是第0轴下标增加1时,元素的地址增加一个元素字节数,在此例子中也就是4 bytes,从1的地址增加4bytes到4的地址。
如果order参数是'A',则返回的数组可能是'C' order也可能是'F' order,甚至是非连续形式'K'。一般不用该参数。
如果order参数是'K',则数组中的元素为元素在内存中的出现顺序。一般不用该参数。
arrange()函数:
返回给定区间内均匀间隔的值。
numpy.arange([start=0, ]stop, [step=1, ]dtype=None)
创建一个数组。数组的值在区间[start, stop)内,相隔step。
linspace()函数:
返回指定区间上均匀间隔的数字。
numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
返回区间[start,stop]上均匀间隔的数字。可以选择性地排除该区间的端点stop,如果endpoint = True, stop是最后一个采样点,否则stop不被数组包含在内。endpoint默认是True。
full()函数
返回由指定值填充的指定形状和数据类型的数组。
numpy.full(shape, fill_value, dtype=None, order='C')
eye()函数
返回一个指定形状的单位矩阵。
numpy.eye(N, M=None, k=0, dtype=<class 'float'>, order='C')
zeros()函数:
创建元素都为0的数组。
numpy.zeros(shape, dtype=float, order='C')
ones()函数:
创建元素都为1的数组。用法同上。
numpy.ones(shape, dtype=None, order='C')
random.random()函数:
返回一个随机浮点值数组,随机值大小在[0.0,1.0)之间。
numpy.random.random(size=None)
size是可选参数,用来定义返回值的形状,默认值是None。当它是整型或整型的元组时,返回值是size形状的随机浮点值数组;当它是None时,返回值是单个随机浮点值。
- 例1 创建一维数组
给array传递一个列表,创建了一个一维数组。
import numpy as np
my_array = np.array([1,2,3,4,5])
print(type(a))//输出:"<class 'numpy.ndarray'>"
print(my_array)//输出:[1 2 3 4 5]
my_new_array = np.zeros((5))//创建包含5个0元素的数组
print(my_new_array)//输出:[0. 0. 0. 0. 0.]
rnd_arr = np.random.random(5)
print(rnd_arr)//输出:[0.28355009 0.11279515 0.2376676 0.00790682 0.70743957]
- 例2 用更多方式创建一维数组
import numpy as np
a = np.array([0, 1, 2, 3, 4])
b = np.array((0, 1, 2, 3, 4))
c = np.arange(5)
d = np.linspace(0, 2*np.pi, 5)
print(a) //输出:[0 1 2 3 4]
print(b) //输出:[0 1 2 3 4]
print(c) //输出:[0 1 2 3 4]
print(d) //输出:[ 0. 1.57079633 3.14159265 4.71238898 6.28318531]
print(a[3]) //输出:3
- 例3 创建多维数组
(1)使用zeros()、ones()等
import numpy as np
d2_arr = np.zeros((2,3))//创建2行3列的二维数组
print(d2_arr[0][1])//输出:0.0
full_array = np.full((2,2), 7) //创建2行2列的二维数组
print(full_array) // 输出:[[ 7. 7.]
// [ 7. 7.]]
d = np.eye(2) //创建单位矩阵
print(d) // 输出:[[ 1. 0.]
// [ 0. 1.]]
(2)使用已有列表创建数组。为了创建一个二维数组,需传递一个列表的列表(或一个序列的序列)给array函数。若想要一个三维数组,需传递一个列表的列表的列表,以此类推。
import numpy as np
my_array = np.array([[4,5],[6,1]])
print(my_array[0][1])//输出:5
print(my_array[0,0], my_array[0,1])//输出:4 5
print(my_array.shape)//输出:(2,2)
a = np.array([[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25],
[26, 27, 28 ,29, 30],
[31, 32, 33, 34, 35]])
print(a[2,4]) //输出:25
2.2 数组的属性
NumPy为数组ndarray提供了很多属性信息。
“dtype”是数组中数据的类型。
“size”是指数组中元素的个数。
数组的形状“shape”是指它的行列数,shape的返回值是一个元组,里面每个数字表示每一维的长度。
“itemsize”是每个项占用的字节数。一个int32有32位,即4个字节。
“ndim”是数组的维数。
“nbytes”是数组中所有数据消耗掉的字节数。需注意这不是数组的开销,数组占用的实际空间会稍微大一点。
- 例1 常用属性
import numpy as np
a = np.array([[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25],
[26, 27, 28 ,29, 30],
[31, 32, 33, 34, 35]])
print(type(a)) //输出:<class 'numpy.ndarray'>
print(a.dtype) //输出:int32
print(a.size) //输出:25
print(a.shape) //输出:(5, 5)
print(a.itemsize) //输出:4
print(a.ndim) //输出:2
print(a.nbytes) //输出:100
- 例2 shape属性
shape属性返回的是一个包含每一维长度的元组。很容易对一维数组产生误解,认为一维数组的shpae是“(1,元素个数 n)”这种样式,但实际上由于它是一维的,所以返回的元组只会包含一个元素,即这种样式:“(元组个数 n,)”,只包含一个数字,表示该数组元素的个数。另外需要说明的是:“(1,元素个数 n)”这种样式是二维数组才具有的,它表示该二维数组只有1行且该行有 n 个元素。
import numpy as np
x = np.arange(5)
y = np.arange(10)
y = np.reshape(y,(2,5))
z = np.reshape(x,(1,5))
print(x)//输出:[0 1 2 3 4]
print(y)//输出:[[0 1 2 3 4]
// [5 6 7 8 9]]
print(z)//输出:[[0 1 2 3 4]]
print(x.shape)//输出:(5,)
print(y.shape)//输出:(2, 5)
print(z.shape)//输出:(1, 5)
2.3 数组的切片
多维数组使用逗号分隔的行列号来切片,行列号从0起始。
- 例1 取行或列
import numpy as np
my_array = np.array([[4,5],[6,1]])
my_array_column = my_array[:,1]//取第二列
print(my_array_column)//输出:[5 1]
my_array_line = my_array[1,:]//取第二行
print(my_array_line)//输出:[6 1]
my_array_line = my_array[0]//取第一行
my_array_line = my_array[1]//取第二行
- 例2 切片
import numpy as np
a = np.array([[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20],
[21, 22, 23, 24, 25],
[26, 27, 28 ,29, 30],
[31, 32, 33, 34, 35]])
print(a[0, 1:4]) //输出:[12 13 14]
print(a[1:4, 0]) //输出:[16 21 26]
print(a[::2,::2]) //输出:[[11 13 15]
// [21 23 25]
// [31 33 35]]
print(a[:, 1]) //[12 17 22 27 32]
数组a的切片按下图进行工作。
- 例3 花式索引
该索引方法可以根据指定的索引获取特定元素。
import numpy as np
a = np.arange(0, 100, 10)
indices = [1, 5, -1]
b = a[indices]
print(a) //输出:[ 0 10 20 30 40 50 60 70 80 90]
print(b) //输出:[10 50 90]
c = a.reshape((2,5))
indices = ((0,1),(1,2))
d = c[indices]
print(d)//输出:[10,70]
- 例4 布尔屏蔽
该索引方法可以根据指定的条件来获取数组中的元素。
import numpy as np
a = np.linspace(0, 2 * np.pi, 50)
b = np.sin(a)
mask = b >= 0//生成一个True、False矩阵。b[i]>=0的位置为True,否则为False。
print(mask)
print(a[mask])
print(b[mask])
mask = (b >= 0) & (a <= np.pi / 2)//生成一个True、False矩阵。b[i]>=0 且 a[i]<=np.pi/2 的位置为True,否则为False。
print(mask)
print(a[mask])
print(b[mask])
- 例5 缺省索引
import numpy as np
a = np.arange(0, 100, 10)
b = a[:5]//缺省索引:获取前5个元素
c = a[a >= 50]//布尔屏蔽
print(b) //输出:[ 0 10 20 30 40]
print(c) //输出:[50 60 70 80 90]
- 例6 可以修改Numpy数组的元素
import numpy as np
my_array = np.array([1,2,3,4,5])
my_array[0] = -1//修改值为-1
print(my_array[0])//输出:-1,而不是1了
- 例7 Where 函数
where() 函数是根据条件返回数组中的值的有效方法。只需要把条件传递给它,它就会返回一个满足条件为真的元组或数组。
numpy.where(condition[, x, y])
condition是布尔型数组。x,y是数组类型,可选项。where的返回值分两种情况:
(1)指定了x与y
当condition里的元素为True时,返回的数组里包含 x 对应位置的元素,否则包含 y 对应位置的元素。
(2)只有condition参数
返回的是索引值元组,元组里包含的是condition里True元素的索引值。
a = np.arange(0, 100, 10)
b = np.where(a < 50)
c = np.where(a >= 50)[0]
print(b) //输出:(array([0, 1, 2, 3, 4]),)
print(c) //输出:[5 6 7 8 9]
d = np.where([[True, False], [True, True]],
... [[1, 2], [3, 4]],
... [[9, 8], [7, 6]])
print(d)//输出:[[1 8]
// [3 4]]
e = np.where([[0, 1], [1, 0]])
print(e)//输出:(array([0, 1],dtype=int64), array([1, 0],dtype=int64))
x = np.arange(9.).reshape(3, 3)
print(np.where( x > 5 ))//输出:(array([2, 2, 2],dtype=int64), array([0, 1, 2],dtype=int64))
print(x[np.where( x > 3.0 )] )//输出:[4 5 6 7 8]
print(np.where(x < 5, x, -1))//输出:[[ 0 1 2]
// [ 3 4 -1]
// [-1 -1 -1]]
2.4 数组操作
(1)reshape函数
reshape()函数
对数组的维度进行调整。
numpy.reshape(a, newshape, order='C')
在不改变数据的情况下,给数组定义新的形状。
import numpy as np
a = np.arange(25)
a = a.reshape((5, 5))
print(a)//输出:[[ 0 1 2 3 4]
// [ 5 6 7 8 9]
// [10 11 12 13 14]
// [15 16 17 18 19]
// [20 21 22 23 24]]
(2)加减乘除
import numpy as np
a = np.array([[1.0, 2.0], [3.0, 4.0]])
b = np.array([[5.0, 6.0], [7.0, 8.0]])
sum = a + b
difference = a - b
product = a * b
quotient = a / b
print("Sum = \n", sum)
print("Difference = \n", difference)
print("Product = \n", product)
print("Quotient = \n", quotient)
输出的结果:
Sum = [[ 6. 8.] [10. 12.]]
Difference = [[-4. -4.] [-4. -4.]]
Product = [[ 5. 12.] [21. 32.]]
Quotient = [[0.2 0.33333333] [0.42857143 0.5 ]]
(3)矩阵乘法
matrix_product = a.dot(b)
print("Matrix Product = ", matrix_product)
输出将是:
[[19. 22.]
[43. 50.]]
(4)逻辑运算
print(a<b)
print(a>b)
输出将是:
[[True True]
[True True]]
[[False False]
[False False]]
(5)其他运算符
a = np.arange(10)
print(a.sum()) //输出:45
print(a.min()) //输出:0
print(a.max()) //输出:9
print(a.cumsum()) //输出:[ 0 1 3 6 10 15 21 28 36 45]
a.cumsum()的结果是a中的当前元素与该元素前的所有元素之和。
参考文献
[1]理解NumPy
[2]NumPy简单入门教程
[3]numpy中 C order与F order的区别是什么?
[4]NumPy v1.15 Manual
[5]python 里 np.array 的shape ( ,)与( ,1)的区别
[6]
[7]
[8]
[9]
[10]
[11]
[12]怎么理解numpy的where()
[13]