1.数组基础
数组的创建
数组与列表的区别
重塑数组的形状
数组的性质
打乱数组
2.数组的数学计算
3.数组的索引与切片
一.数组基础
1.数组的创建
前提:
import numpy as np
方法一:array()
语法格式:np.array()
import numpy as np
data=np.array([1,2,3,4])
print(data)
[1 2 3 4]
方法二:arange()
语法格式:np.arange()
np.arange()与range()函数具有相同的用法,np.arange(start(初始值),stop(终止值不包括),step(步长))
c=np.arange(5)#默认初始值为0,终止值为5(不包括),步长为1
d=np.arange(0,5)#设置初始值为0,终止值为5(不包括),步长为1
e=np.arange(0,10,2)#设置初始值为0,终止值为10(不包括),步长为2
print(c)
print(d)
print(e)
[0 1 2 3 4]
[0 1 2 3 4]
[0 2 4 6 8]
方法三:random()
语法格式:np.random.randint()/np.random.random()/.......
1.random.rand(m,n):生成一个形状为m行n列的数组,数组中的元素是从 [0, 1)
区间内均匀分布的随机数
import numpy as np
arr = np.random.rand(2, 3)
print(arr)
[[0.29261771 0.09707814 0.00934441]
[0.00613357 0.26025766 0.87291032]]
2.random.randn(m,n):生成一个形状为m行n列的数组,数组中的元素是从标准正态分布(均值为 0,方差为 1)中抽取的随机数。
import numpy as np
arr = np.random.randn(2, 3)
print(arr)
[[-2.74944565 -0.83960342 1.75950728]
[-1.59994357 -0.00361855 -0.19142074]]
3.random.randint(low,height,size):生成一个形状为size的数组,数组中的元素是从[low, high)
区间内均匀分布的随机整数。如果high
为None
,则区间为[0, low)
import numpy as np
arr = np.random.randint(1, 10, size=(2, 3))
print(arr)
[[3 8 3]
[4 4 1]]
4.random.uniform(low=0.0, high=1.0, size=None):生成一个形状为 size 的数组,数组中的元素是从 [low, high) 区间内均匀分布的随机浮点数。
import numpy as np
arr = np.random.uniform(1.0, 10.0, size=(2, 3))
print(arr)
[[5.54118384 2.73051364 8.92094903]
[9.88483207 7.60553753 2.51431325]]
5.random.choice(a, size=None, replace=True, p=None):从一维数组 a 中随机抽取元素,生成形状为 size 的数组。replace 参数决定抽样是否有放回,p 参数为数组中每个元素对应的概率。
import numpy as np
arr = np.random.choice([1, 2, 3, 4, 5], size=(2, 3), replace=True,
p=[0.1, 0.2, 0.3, 0.2, 0.2])
print(arr)
[[1 3 3]
[3 3 4]]
6.random.shuffle(x):就地打乱一维数组 x 的元素。注意这个函数会修改原数组,不会返回新数组。
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
np.random.shuffle(arr)
print(arr)
[4 1 5 3 2]
7.random.permutation(x):随机排列一维数组 x 的元素,并返回打乱后的新数组。如果 x 是一个整数,则返回一个 [0, x) 的随机排列。
import numpy as np
arr = np.random.permutation([1, 2, 3, 4, 5])
print(arr)
[3 5 4 1 2]
8.random.seed(seed=None):设置随机数生成器的种子。种子值相同,生成的随机数序列也会相同。
种子值大体可以这样理解:种子值就是一种确定的随机数生成的算法,不同的种子值对应着不同的算法
import numpy as np
np.random.seed(42)
arr1 = np.random.randn(2)
print(arr1)
np.random.seed(42)
arr2 = np.random.randn(2)
print(arr2)
print(arr1 == arr2)
[ 0.49671415 -0.1382643 ]
[ 0.49671415 -0.1382643 ]
[ True True]
9.random.binomial(n, p, size=None):生成一个形状为 size 的数组,数组中的元素是从二项分布中抽取的随机数,其中 n 为试验次数,p 为成功的概率。输出的结果数组中的每一个元素代表的是实验成功的次数,如第一行:分别成功了7,8,6次
import numpy as np
arr = np.random.binomial(10, 0.5, size=(2, 3))
print(arr)
[[7 8 6]
[7 2 5]]
10.random.normal(loc=0.0, scale=1.0, size=None):生成一个形状为 size 的数组,数组中的元素是从正态分布(均值为 loc,标准差为 scale)中抽取的随机数。
import numpy as np
arr = np.random.normal(0, 1, size=(2, 3))
print(arr)
[[0.49185269 0.16229395 0.59812581]
[1.0424101 0.25177905 0.07547117]]
方法四:特殊数组的创建
- zeros:零矩阵
- ones:一矩阵
- empty:随意矩阵(空矩阵)
- eye:对角矩阵
import numpy as np
print("1.零矩阵")
x1=np.zeros((3,3),dtype=float)
print(x1)
print("2.一矩阵")
x2=np.ones((3,3),dtype=int)
print(x2)
print("3.随意矩阵")
x3=np.empty((3,3),dtype=object)
print(x3)
print("4.对角矩阵(单位矩阵)")
#参数表示几行几列
x4=np.eye(4)
print(x4)
1.零矩阵
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
2.一矩阵
[[1 1 1]
[1 1 1]
[1 1 1]]
3.随意矩阵
[[None None None]
[None None None]
[None None None]]
4.对角矩阵(单位矩阵)
[[1. 0. 0. 0.]
[0. 1. 0. 0.]
[0. 0. 1. 0.]
[0. 0. 0. 1.]]
矩阵的用法:生成一个相同维数的矩阵
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]
- arange:等差数组
- logspace:等比数组
语法格式:numpy.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None, axis=0)
start
:序列的起始值(对数值)。stop
:序列的结束值(对数值)。num
:要生成的样本数量,默认为50。endpoint
:如果为True(默认值),则包含stop
值;如果为False,则不包含stop
值。base
:对数的底数,默认为10(表示常用对数)。如果设置为numpy.e
,则生成的是自然对数刻度上的数值。dtype
:输出数组的类型,默认为float64
。axis
:沿指定轴生成样本,默认是0轴(即生成一维数组)。
import numpy as np
# 生成从10^0到10^2(即1到100)之间按指数级增长的5个数值
arr = np.logspace(0, 2, num=5)
print(arr)
[ 1. 10. 100. 1000. 10000.]
print("等差数列:arange")
#(start,stop,step)
data = np.arange(1,11,2)
print(data)
print("等比数列:logspace")
data=np.logspace(np.log10(1),np.log10(10),num=10)
data1=np.logspace(1,32,4)
print(data)
print(data1)
等差数列:arange
[1 3 5 7 9]
等比数列:logspace
[ 1. 1.29154967 1.66810054 2.15443469 2.7825594 3.59381366
4.64158883 5.9948425 7.74263683 10. ]
[1.00000000e+01 2.15443469e+11 4.64158883e+21 1.00000000e+32]
2.数组与列表的区别
1.numpy生成的数组没有逗号,而列表生成的有逗号
2.同样可以使用索引和切片,且都是左闭右开,但是数组输出的切片还是没有逗号
3.当对数组和列表进行乘法计算时,列表是重复输出,而数组是将其中的每一个元素进行乘法操作
import numpy as np
a=[1,2,3,4,5,6,7,8,9]
b=np.array([1,2,3,4,5,6,7,8,9])
print(a)
print(b)
print(type(a))
print(type(b))
print(a[1])
print(b[1])
print(a[0:2])
print(b[0:2])
print(a*2) #表示列表重复两遍
print(b*2) #表示数组各个元素乘2
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1 2 3 4 5 6 7 8 9]
<class 'list'>
<class 'numpy.ndarray'>
2
2
[1, 2]
[1 2]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[ 2 4 6 8 10 12 14 16 18]
3.重塑数组的形状
1.reshape
语法格式:新数组=数组.reshape(行,列)
-
返回新数组:
reshape
函数返回一个新的数组对象,不改变原数组。 -
元素顺序:
reshape
会保持原数组中的元素顺序不变。 -
严格性:
reshape
要求新形状的总元素数量必须与原数组的总元素数量相同。
1.使用reshape时,不足数量会报错
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
b=a.reshape((4, 2))
print(b)
ValueError: cannot reshape array of size 6 into shape (4,2)
2.在reshape()时,如果数据量太大,且直到目标数组的行数/列数,则可以将列数/行数用-1代替
import numpy as np
data = np.array([[1,2,3,4],[5,6,7,8]])
print(data.shape) #输出data数组的形状(既表示几行几列)
print(data)
print("改变形状reshape")
print(data.reshape(2,2,2))#三维的
print("可以先设置行数,然后用-1代表列数") #同理-1也可表示行数
print(data.reshape(2,-1))#2行的
print(data.reshape(2,2,-1))#2行2列的三维
print(data.reshape(1,-1))#变成1行的(由多维变为1维)
print(data.reshape(-1))#变为1维的
(2, 4)
[[1 2 3 4]
[5 6 7 8]]
改变形状reshape
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
可以先设置行数,然后用-1代表列数
[[1 2 3 4]
[5 6 7 8]]
[[[1 2]
[3 4]]
[[5 6]
[7 8]]]
[[1 2 3 4 5 6 7 8]]
[1 2 3 4 5 6 7 8]
2.resize
语法格式:新数组=数组.resize(行,列)
-
就地修改:
resize
函数直接修改原数组,不返回新的数组对象。 -
元素顺序:
resize
也试图保持原数组中的元素顺序不变,但由于可能涉及内存重新分配,其行为在某些极端情况下可能略有不同。 -
内存布局:
resize
通常需要重新分配内存,因为它就地修改数组大小。 -
灵活性:
resize
在改变数组大小时可能会引入填充值(通常是零),特别是当新形状的总元素数量多于原数组的总元素数量时。相反,如果新形状的总元素数量少于原数组的总元素数量,则一些元素会被丢弃。
使用resize时,不足数量会补上0
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]]) #由此可见a是一个2行3列的数组
a.resize((4, 2)) #将a变为4行2列的,不足的补上0
print(a)
[[1 2]
[3 4]
[5 6]
[0 0]]
reshape与resize的具体表现:
import numpy as np
data=np.arange(12)
print(data)
data.resize(4,3)
print(data)
data1=np.arange(12)
data2=data1.reshape(3,4)
print(data1)
print(data2)
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
[ 0 1 2 3 4 5 6 7 8 9 10 11]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
3.ravel
语法格式:numpy.ravel(数组,order)
用于将多维变为1维
参数order为A,C,K,F四个:
A:如果数组是Fortran连续的,则按列主序展平;否则,按行主序展平。
C:默认顺序,按行主序,既从第一行开始读取
K:尽可能按输入数组的顺序展平,但不保证是连续的。
F:按列主序,既从第一列开始读取
行主序是C语言和许多其他低级编程语言中多维数组默认的存储顺序。相比之下,列主序(Column-major order)是Fortran语言和某些其他环境中多维数组的默认存储顺序
以二维数组为例,如果我们有一个2x3的数组:
1 2 3
4 5 6
在行主序存储中,这个数组的内存布局将是:
1, 2, 3, 4, 5, 6
import numpy as np
arr=np.array([1,3,5,7,2,4,6,8]).reshape(2,-1)
A_arr = np.ravel(arr,'A')
C_arr = np.ravel(arr,'C')
K_arr = np.ravel(arr,'K')
F_arr = np.ravel(arr,'F')
print(arr)
print('A:',A_arr)
print('C:',C_arr)
print('K:',K_arr)
print('F:',F_arr)
[[1 3 5 7]
[2 4 6 8]]
A: [1 3 5 7 2 4 6 8]
C: [1 3 5 7 2 4 6 8]
K: [1 3 5 7 2 4 6 8]
F: [1 2 3 4 5 6 7 8]
4.T(转置)
语法格式:数组.T/数组.transpose()
import numpy as np
data=np.arange(0,8).reshape(2,-1)
data1=data.T
print(data)
print("方法1:")
print(data1)
print("方法2:")
data2=data.transpose()
print(data2)
[[0 1 2 3]
[4 5 6 7]]
方法1:
[[0 4]
[1 5]
[2 6]
[3 7]]
方法2:
[[0 4]
[1 5]
[2 6]
[3 7]]
4.数组的属性
import numpy as np
x=np.array([[1,2,3],[1,2,3]])
print(x)
print(type(x))
print(x.ndim)#维数
print(x.size)#元素个数
print(x.dtype)#数据类型
print(x.shape)#数组的形状
[[1 2 3]
[1 2 3]]
<class 'numpy.ndarray'>
2
6
int32
(2, 3)
5.打乱数组
它用于就地打乱一个列表的元素顺序。这意味着该函数会直接修改传入的列表,而不是返回一个新的列表。
import numpy as np
data = np.arange(10)
print(data)
#对数据进行打乱
np.random.shuffle(data)
print(data)
data1=data.reshape(2,5)
print(data1)
np.random.shuffle(data1)
print(data1)
[0 1 2 3 4 5 6 7 8 9]
[3 5 9 7 4 8 0 2 1 6]
[[3 5 9 7 4]
[8 0 2 1 6]]
[[8 0 2 1 6]
[3 5 9 7 4]]
二.数组的数学运算
1.基本运算(+-*/)
- 标量与矢量运算:既矢量中的每一个元素对应标量进行一一的+-*/
- 矢量与矢量运算:既进行点乘
- 矢量与矢量的乘法:使用np.dot(a,b)
import numpy as np
a=10#数值看做标量
b=np.array([[1,2],[3,4]])#看作矢量
c=np.array([[5,6],[7,8]])
print("矢量与标量运算:")
print('+:',a+b)
print('-:',a-b)
print('*:',a*b)
print('/:',a/b)
print("矢量与矢量运算,对应元素点乘,点除")
print('+:',b+c)
print('-:',b-c)
print('*:',b*c)
print('/:',b/c)
print("矩阵的乘法:")
print(np.dot(b,c))
矢量与标量运算:
+: [[11 12]
[13 14]]
-: [[9 8]
[7 6]]
*: [[10 20]
[30 40]]
/: [[10. 5. ]
[ 3.33333333 2.5 ]]
矢量与矢量运算,对应元素点乘,点除
+: [[ 6 8]
[10 12]]
-: [[-4 -4]
[-4 -4]]
*: [[ 5 12]
[21 32]]
/: [[0.2 0.33333333]
[0.42857143 0.5 ]]
矩阵的乘法:
[[19 22]
[43 50]]
2.常用计算
语法格式:np.计算方法(数组,axis=0/1)
axis表示要计算的方式:0表示列,1表示行
import numpy as np
data = np.random.uniform(0,10,(3,3))
print(data)
print("向上取整:",np.ceil(data))
print("向下取整:",np.floor(data))
print("四舍五入:",np.rint(data))
print("是否为空:",np.isnan(data))#用于数据挖掘,剔除数据为空的 nan:not a number的缩写
print("数据预处理:",np.where(data>5,1,0))#表示 1 if data>5 else 0
print("统计函数(sum):")
print("求矩阵总合:",np.sum(data))
print("按列求和:",np.sum(data,axis=0))
print("按行求和:",np.sum(data,axis=1))
print("求平均值(mean,average):",np.mean(data))
print("按行求平均值",np.mean(data,axis=1))
print("按列求平均值",np.average(data,axis=0))
print("最大值与最小值(max,min):",np.min(data),np.max(data))
print("列最大值:",np.max(data,axis=0))
print("行最小值:",np.min(data,axis=1))
print("标准准差(std),方差(var):",np.std(data),np.var(data))
print("按行求标准差,方差:",np.std(data,axis=1),np.var(data,axis=1))
print("求出最大/小值的索引(argmax/argmin):",np.argmax(data),np.argmin(data))
print("按行求最大/小值:",np.argmax(data,axis=1),np.argmin(data,axis=1))#记住索引每行从0开始
[[9.32090743 2.0031685 2.9991987 ]
[3.91186083 2.18853395 7.06299696]
[4.18550087 6.56214963 4.27687221]]
向上取整: [[10. 3. 3.]
[ 4. 3. 8.]
[ 5. 7. 5.]]
向下取整: [[9. 2. 2.]
[3. 2. 7.]
[4. 6. 4.]]
四舍五入: [[9. 2. 3.]
[4. 2. 7.]
[4. 7. 4.]]
是否为空: [[False False False]
[False False False]
[False False False]]
数据预处理: [[1 0 0]
[0 0 1]
[0 1 0]]
统计函数(sum):
求矩阵总合: 42.51118908362143
按列求和: [17.41826913 10.75385209 14.33906787]
按行求和: [14.32327462 13.16339175 15.02452271]
求平均值(mean,average): 4.723465453735715
按行求平均值 [4.77442487 4.38779725 5.00817424]
按列求平均值 [5.80608971 3.58461736 4.77968929]
最大值与最小值(max,min): 2.0031684976548347 9.320907428558517
列最大值: [9.32090743 6.56214963 7.06299696]
行最小值: [2.0031685 2.18853395 4.18550087]
标准准差(std),方差(var): 2.307889427270182 5.326353608505489
按行求标准差,方差: [3.2404626 2.01824743 1.09945951] [10.50059784 4.07332267 1.20881122]
求出最大/小值的索引(argmax/argmin): 0 1
按行求最大/小值: [0 2 1] [1 1 0]
data1=np.array([[1,2],[3,4]])
print("矩阵:",data1)
print(np.cumsum(data1,dtype=int))
print("当前元素与前一元素的和:",np.cumsum(data1,axis=1))
print("当前元素与前一元素的乘:",np.cumprod(data1,axis=1))
矩阵: [[1 2]
[3 4]]
[ 1 3 6 10]
当前元素与前一元素的和: [[1 3]
[3 7]]
当前元素与前一元素的乘: [[ 1 2]
[ 3 12]]
3.判断函数
import numpy as np
data = np.array([[1,2,3],[4,5,6],[7,8,9]])
print("1:",data)
print("2:",data>5)
print("3:",(data>5).any(axis=1))#axis=1表示行,既若第一行没有有一个元素满足,返回False,若第二行至少有一个元素满足,则返回True
print("4:",data.all())#所有元素都满足.返回True
1: [[1 2 3]
[4 5 6]
[7 8 9]]
2: [[False False False]
[False False True]
[ True True True]]
3: [False True True]
4: True
三.索引与切片
import numpy as np
data = np.arange(0,12).reshape(3,4)
print(data)
print("取第二行:",data[1])
print("取第二行第二个:",data[1][1])
print("取第二行到最后一行:",data[1:])
print("取第二行到最后一行,第二列到最后一列:",data[1:,1:])
print(data[1:][1:])#表示分开处理,第一次先去掉第一行,然后对处理后的数据在去掉第二行
print("花式索引输出位置为(1,1),(2,2):",data[[1,2],[1,2]])
"""
笛卡尔积np.ix_
A=[1,2]
b=[a,b]
则两集合的笛卡尔积是:(1,a),(1,b),(2,a),(2,b)
"""
print("输出(1,1),(1,2),(2,1),(2,2):",data[np.ix_([1,2],[1,2])])
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
取第二行: [4 5 6 7]
取第二行第二个: 5
取第二行到最后一行: [[ 4 5 6 7]
[ 8 9 10 11]]
取第二行到最后一行,第二列到最后一列: [[ 5 6 7]
[ 9 10 11]]
[[ 8 9 10 11]]
花式索引输出位置为:(1,1),(2,2): [ 5 10]
输出(1,1),(1,2),(2,1),(2,2): [[ 5 6]
[ 9 10]]
四.布尔索引
import numpy as np
data=np.array([[11,21,31],[41,51,61],[71,81,91]])
print(data)
print(data>51) #输出一个布尔数组,表示data中每个元素是否大于51
print("使用布尔值作为索引:",data[(data>51)&(data<71)]) #这行代码使用布尔索引来选择data中大于51且小于71的元素。&操作符用于组合两个布尔条件。
print("判断是否为空:",np.isnan(data)) #np.isnan()函数检查数组中的元素是否是NaN(不是一个数字)。因为data中没有NaN值
print("判断非空:",data[~np.isnan(data)]) #这里使用~操作符对np.isnan(data)的结果进行取反,然后选择所有非NaN的元素。因为data中没有NaN值,所以这会选择data中的所有元素
[[11 21 31]
[41 51 61]
[71 81 91]]
[[False False False]
[False False True]
[ True True True]]
使用布尔值作为索引: [61]
判断是否为空: [[False False False]
[False False False]
[False False False]]
判断非空: [11 21 31 41 51 61 71 81 91]