一、Numpy介绍

NumPy是Python中科学计算的基础包,它的核心是 ndarray(多维数组)对象,简称数组。数组由同种类型的元素组成,可以通过整数元组进行索引。在Numpy中,维度称为轴(axis),轴的个数称为秩(rank).。比如[1,2,3]是一维数组,具有一个轴,由3个元素组成,即它的长度为3。二维数组由1或多个一维数组组成,比如[[1,2,3],[2,3,4]]。三维数组由1或多个二维数组组成,以此类推。

二、安装

pip install numpy

三、数组创建

np.array()

>>> import numpy as np
>>> np.array([1,2,3],dtype=int) #创建一维数组,可指定元素类型
array([1, 2, 3])
>>> np.array([[1,2,3],[4,5,6]]) #创建二维数组
array([[1, 2, 3],
       [4, 5, 6]])
#同理创建多维数组

np.random.rand(m,n)或者np.random.random((m,n))------创建m行n列,由0-1的随机数构成的数组,注意后者传入的参数是一个元组

>>> np.random.rand(2,3)
array([[0.96520381, 0.3969341 , 0.36751751],
       [0.33390612, 0.46732563, 0.54680012]])

np.arange(start,stop,step)------创建一维数组,用法同python中的range

>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(1,10) #左闭右开区间
array([1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.arange(1,10,2)#指定步幅为2
array([1, 3, 5, 7, 9])

np.linspace(start,stop,num)------指定起止值,创建指定个数的等差一维数组

>>> np.linspace(10,100,6)
array([ 10.,  28.,  46.,  64.,  82., 100.])

np.ones((m,n))-----------创建一个m行n列的全1数组

>>> np.ones((3,4))
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])

np.zeros((m,n))--------------创建一个m行n列的全0数组

>>> np.zeros((2,3))
array([[0., 0., 0.],
       [0., 0., 0.]])

np.indices((m,n))---------创建m行,n列的3维数组;如果参数元组内传入i个元素,则创建(i+1)维数组,内部元素为i个i维数组

>>> np.indices((2,3))
array([[[0, 0, 0],
        [1, 1, 1]],

       [[0, 1, 2],
        [0, 1, 2]]])

四、数组堆叠与拆分

堆叠

np.vstack() - 行堆叠

np.hstack() - 列堆叠

>>> m
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> n
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
>>> np.vstack((m,n))
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]])
>>> np.hstack((m,n))
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19])

拆分

np.vsplit() - 行拆分,即沿垂直轴拆分,可以指定平均拆分成几等分,也可以通过元组中的元素来指定从哪些行后面进行拆分

np.hsplit() - 列拆分,即沿水平轴拆分,可以指定平均拆分成几等分,也可以通过元组中的元素来指定从哪些列后面进行拆分

>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> np.vsplit(a,3) #按行拆分成3等分
[array([[0, 1, 2, 3, 4]]), array([[5, 6, 7, 8, 9]]), array([[10, 11, 12, 13, 14]])]
>>> np.vsplit(a,(2,)) #从第2行后面进行拆分
[array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]), array([[10, 11, 12, 13, 14]])]
>>> np.hsplit(a,5) #按列拆分成5等分
[array([[ 0],
       [ 5],
       [10]]), array([[ 1],
       [ 6],
       [11]]), array([[ 2],
       [ 7],
       [12]]), array([[ 3],
       [ 8],
       [13]]), array([[ 4],
       [ 9],
       [14]])]
>>> np.hsplit(a,(2,3)) #分别从第二列和第3列后进行拆分
[array([[ 0,  1],
       [ 5,  6],
       [10, 11]]), array([[ 2],
       [ 7],
       [12]]), array([[ 3,  4],
       [ 8,  9],
       [13, 14]])]

五、运算

算数运算:+,-,*,/,//,%,**-------------每个数组中对应元素进行运算

>>> a = np.array([1,2,3,4])
>>> b = np.array([5,6,7,8])
>>> a+b
array([ 6,  8, 10, 12])
>>> a-b
array([-4, -4, -4, -4])
>>> a*b
array([ 5, 12, 21, 32])
>>> a/b
array([0.2       , 0.33333333, 0.42857143, 0.5       ])
>>> a//b
array([0, 0, 0, 0])
>>> a%b
array([1, 2, 3, 4])
>>> a**2
array([ 1,  4,  9, 16])

比较运算:==,<,<=,>,>=,!=----------------------数组中每个元素都进行相应比较,返回bool值组成的数组

>>> a
array([1, 2, 3, 4])
>>> a==2
array([False,  True, False, False])
>>> a>2
array([False, False,  True,  True])
>>> a>=2
array([False,  True,  True,  True])
  • 逻辑运算:逻辑与(&),逻辑或(|),逻辑非(~)


    >>> a = np.arange(15).reshape(3,5)
    >>> a
    array([[ 0,  1,  2,  3,  4],
           [ 5,  6,  7,  8,  9],
           [10, 11, 12, 13, 14]])
    >>> (a>3)&(a<10)
    array([[False, False, False, False,  True],
           [ True,  True,  True,  True,  True],
           [False, False, False, False, False]])
    >>> (a<3)|(a>10)
    array([[ True,  True,  True, False, False],
           [False, False, False, False, False],
           [False,  True,  True,  True,  True]])
    >>> a[~(a%2==0)]
    array([ 1,  3,  5,  7,  9, 11, 13])


六、索引和切片

一维数组

同python列表操作一样

x[i]---x数组中索引为i的元素,索引从0开始

x[-i]---索引倒数第i个元素

x[m:n]--不包含索引为n的元素

x[m:n:i]--指定步幅为i

>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> a[2]
2
>>> a[-1]
9
>>> a[3:8]
array([3, 4, 5, 6, 7])
>>> a[3:8:2]
array([3, 5, 7])

多维数组

每个轴可以有一个索引。这些索引以逗号分隔的元组给出,当提供的索引少于轴的数量时,缺失的索引被认为是完整的切片:

以二维数组为例:

>>> a
array([[  1,   2,   3,   4],
       [ 10,  20,  30,  40],
       [100, 200, 300, 400]])
>>> a[2] #取第3行数据
array([100, 200, 300, 400])
>>> a[:,2] #取第3列数据
array([  3,  30, 300])
>>> a[0:2,2] #取前2行第3个数
array([ 3, 30])
>>> a[1,2] #取第2行第3个数
30

索引数组

单个索引数组

只对第1个维度进行索引操作
结果形式:将索引数组里面的每个索引值,替换成数组被该索引值所索引的结果
以x数组为例,索引数组为一维数组np.array([1,1,3,4]),那么x[np.array([1,2,3,4])]----结果为array([x[1],x[1],x[3],x[4]])
以x数组为例,索引数组为二维数组[[1,1],[3,4]],那么x[[[1,1],[3,4]]]----结果为[[x[1],x[1]],[x[3],x[4]]]
>>> a = np.linspace(2,20,10,dtype=int)
>>> a
array([ 2,  4,  6,  8, 10, 12, 14, 16, 18, 20])
>>> a[[1,2,3,4]] #传入列表索引和一维数组索引等效
array([ 4,  6,  8, 10])
>>> a[np.array([1,2,3,4])] #索引数组为一维数组
array([ 4,  6,  8, 10])
>>> a[np.array([[1,2],[3,4]])]#索引数组为二维数组
array([[ 4,  6],
       [ 8, 10]])

多个索引数组

为多个维度提供索引,每个维度的索引数组必须具有相同的形状 。
>>> a = np.indices((2,3)) #创建一个3维数组
>>> a
array([[[0, 0, 0],
        [1, 1, 1]],

       [[0, 1, 2],
        [0, 1, 2]]])
>>> a[np.array([0,1]),np.array([0,1])] #对前两个维度进行索引,结果相当于np.array([a[0][0],a[1][1]])
array([[0, 0, 0],
       [0, 1, 2]])
>>> a[np.array([0,1]),np.array([0,1]),np.array([1,2])] #对3个维度分别索引,结果相当于np.array(a[0][0][1],a[1][1][2])
array([0, 2])

索引数组和整数相结合

将整数理解为和索引数组等长的以该整数为元素的数组

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

布尔索引

与原始数组具有相同形状的布尔数组

在获取元素的时候,只返回索引值为True的元素所组成的数组,其它元素舍弃
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> b = a > 3
>>> b
array([[False, False, False, False,  True],
       [ True,  True,  True,  True,  True],
       [ True,  True,  True,  True,  True]])
>>> a[b] #返回a中大于3的元素所组成的数组
array([ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a[b] = 0 #赋值,只对索引数组中元素为True的位置进行赋值
>>> a
array([[0, 1, 2, 3, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

对于数组的每个维度,给出一个一维布尔数组以及想要的切片

请注意,一维布尔数组的长度必须与要切片的尺寸(或轴)的长度一致
>>> a = np.arange(15).reshape((3,5))
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> b1 = np.array([True,False,True])
>>> b2 = np.array([True,False,True,False,True])
>>> a[b1,:]
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14]])
>>> a[:,b2]
array([[ 0,  2,  4],
       [ 5,  7,  9],

七、数组常用属性和方法

常用属性

ndim - 数组的轴(维度)的个数

shape - 数组的维度。这是一个整数的元组,表示每个维度中数组的大小。对于m行n列的矩阵数组,返回的是(m,n)

size - 数组中所有元素的个数,等于shape的元素的乘积

dtype - 数组中元素类型的对象,可以继续通过该对象的name属性来获取元素类型的名称

itemsize - 数组中每个元素的字节大小,比如元素类型为int64的数组,每个元素的字节大小为64/8=8个字节

T - 转置操作,不修改原数组

>>> a = np.arange(15).reshape((3,5))
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a.ndim
2
>>> a.shape
(3, 5)
>>> a.size
15
>>> a.dtype
dtype('int64')
>>> a.dtype.name
'int64'
>>> a.itemsize
8
>>> a.T
array([[ 0,  5, 10],
       [ 1,  6, 11],
       [ 2,  7, 12],
       [ 3,  8, 13],
       [ 4,  9, 14]])

常用方法

tolist() - 转换成python列表

astype(类型) - 转换数组元素类型

min() - 求所有元素最小值,返回单个值

max() - 求所有元素最大值

sum() - 求总和

mean() - 求平均值

min(axis) - 参数axis=1,按行求最小值,axis=0,按列求最小值,返回数组类型

max(axis) - 同上,求最大值

mean(axis=None) - 同上,求均值

argmin() - 求最小值所对应的索引值,如果是多维数组,则为拆分为一维数组后的索引值

argmin(axis) - 参数axis=1,按行求最小值所对应的索引值,axis=0,按列求最小值所对应的索引值,返回数组类型

argmax() - 同上,求最大值对应索引值

argmax(axis) - 同上,求最大值对应索引值,返回数组类型

view() - 视图,浅拷贝

copy()- 深拷贝

reshape() - 修改数组形状,但不会修改原数组,比如reshape(m,n)表示修改原数组为m行n列的二维数组

resize() - 修改数组形状,并且会修改原数组

ravel() - 返回数组降维后的一维数组,但不会修改原数组

flatten() - 同ravel(),返回数组降维后的一维数组,但不会修改原数组

>>> a = np.arange(15) #创建一个一维数组
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a.tolist() #转成python列表形式
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> a.astype(float) #转换数组元素类型为float类型
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.,
       13., 14.])
>>> b = a.reshape(3,5) #修改数组为3行5列的二维数组
>>> b
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a #reshape后,没有修改原数组
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a.resize(3,5) #resize修改了原数组
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a.max() #返回数组内元素最大值
14
>>> a.argmax() #返回最大值在一维数组中的索引值
14
>>> a.argmax(axis=1) #按行求最大值所对应的索引值
array([4, 4, 4])
>>> a.ravel() #降维成一维数组
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a.flatten() #降维成一维数组
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
>>> a #ravel()和flatten()都没有修改原数组
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> c = a.copy() #对a进行深拷贝
>>> d = a.view() #对a进行浅拷贝
>>> c
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> d
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> c[c==1] = 1111 #将深拷贝过的c数组中元素1修改为1111
>>> d[d==2] = 222 #将浅拷贝过的d数组中元素2修改为222
>>> a #修改浅拷贝过的数组,a数组中的元素发生相应变化
array([[  0,   1, 222,   3,   4],
       [  5,   6,   7,   8,   9],
       [ 10,  11,  12,  13,  14]])

以上介绍的只是numpy的部分知识,想深入了解numpy,可参考numpy中文文档