ndarray数据类型和相关使用
1、什么是ndarray
n dimension array n维数组
2、创建ndarray
2.1使用np.array()由Python list创建
注意:
- numpy默认ndarray的所有元素的类型是相同的
- 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int
例1:l = [1,2,3,4,5]
n = np.array(l)
>>n:array([1, 4, 2, 5, 3])
例2:列表l = [1,2,3,'4',5.0]
n = np.array(1)
>>n :array(['1', '2', '3', '4', '5.0'], dtype='<U11')
2.2 使用np 的routines函数创建
routines常规方法.
包含以下常见创建方法:
- np.ones(shape, dtype=None, order=‘C’)
生成全是1的ndarray,默认dtype数据类型是浮点数
np.ones(shape=(4,5,3), dtype=np.int8)
np.zeros(shape=[3,5], dtype=np.int)
>>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, 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]]], dtype=int8)
- np.zeros(shape, dtype=float, order=‘C’)
生成全是0的ndarray,默认dtype数据类型是浮点数
np.zeros(shape=[3,5], dtype=np.int)
array([[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]])
- np.full(shape, fill_value, dtype=None, order=‘C’)
使用指定的值填充ndarray
np.full(shape=(4,5), fill_value=8, dtype=np.float)
array([[8., 8., 8., 8., 8.],
[8., 8., 8., 8., 8.],
[8., 8., 8., 8., 8.],
[8., 8., 8., 8., 8.]])
#np.full(shape=(4,5),fill_value=8)#自行推断为整数8,使用指定的值填充
array([[8, 8, 8, 8, 8],
[8, 8, 8, 8, 8],
[8, 8, 8, 8, 8],
[8, 8, 8, 8, 8]])
- np.eye(N, M=None, k=0, dtype=float)
【意义】对角线上全是1, 其他位置全是0, 只能是2维;
【参数】:可位置传参,也可关键字传参
N:行数,M:列数,为None默认其与N值一致;
k:为正整数向上移动对角线,为负向下移动对角线;
dtype:默认为float;
行列数相同的矩阵,叫做方阵;
主对角线上全是1, 其他位置全是0的方阵,我们叫做满秩矩阵. 有解
np.eye(5)
>>array([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.]])
np.eye(5, k=1)
>>array([[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.],
[0., 0., 0., 0., 0.]])
np.eye(3,5,-1,int)
>>array([[0, 0, 0, 0, 0],
[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0]])
- np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
【意义】对指定区间进行线性等分
【参数】start,stop:区间起止范围,endpoint:是否包含端点,默认包含;num:等分份数,默认50份;retstep:是否打印步长,默认不打印;dtype:输出类型根据结果自行推断,也可给定
np.linspace(1,50)
>>array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 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., 36., 37., 38., 39.,
40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50.])
np.linspace(0,100, num=100, endpoint=False, retstep=True)
>>(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., 24., 25.,
26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38.,
39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.,
52., 53., 54., 55., 56., 57., 58., 59., 60., 61., 62., 63., 64.,
65., 66., 67., 68., 69., 70., 71., 72., 73., 74., 75., 76., 77.,
78., 79., 80., 81., 82., 83., 84., 85., 86., 87., 88., 89., 90.,
91., 92., 93., 94., 95., 96., 97., 98., 99.]), 1.0)
- np.arange([start, ]stop, [step, ]dtype=None)
【意义】和python原生的range是一样.左闭右开.
【参数】start,stop:区间起止范围;step:步长,当步长step是小数的时候,推荐使用np.linspace();
np.arange(0, 100, step=2)
>>array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98])
- np.random.randint(low, high=None, size=None, dtype=‘l’)
np.random下面的东西都是用来生成随机数.但都是伪随机数,加入种子后,生成的随机数都是一致的
【意义】在指定的范围随机生成一个随机整数,左闭右开
【参数】low,hign:随机生成数的范围;size:随机生成数的shape样式,默认为None,只生成一个随机数,指定样式后,按照样式生成对应的随机数数组,随机数可重复;dtype:默认值是’np.int’
#加入种子,在相同的电脑一直生成该数组
np.random.seed(2)
np.random.randint(0,100, size=(4,5))
array([[40, 15, 72, 22, 43],
[82, 75, 7, 34, 49],
[95, 75, 85, 47, 63],
[31, 90, 20, 37, 39]])
np.random.randint(0,100, size=(3,3,11))
array([[[67, 4, 42, 51, 38, 33, 58, 67, 69, 88, 68],
[46, 70, 95, 83, 31, 66, 80, 52, 76, 50, 4],
[90, 63, 79, 49, 39, 46, 8, 50, 15, 8, 17]],
[[22, 73, 57, 90, 62, 83, 96, 43, 32, 26, 8],
[76, 10, 40, 34, 60, 9, 70, 86, 70, 19, 56],
[82, 1, 68, 40, 81, 61, 70, 97, 18, 84, 90]],
[[87, 22, 43, 52, 74, 72, 90, 99, 91, 96, 16],
[55, 21, 43, 93, 80, 40, 70, 74, 37, 59, 17],
[15, 30, 77, 26, 39, 63, 20, 22, 59, 49, 27]]])
- np.random.randn(d0, d1, …, dn)
【意义】从“标准正态分布”中返回一个(或多个)样本。
【拓展】正态分布:
正态分布有两个参数,即期望(均数)μ和标准差σ,σ2为方差。
正态分布公式正态分布具有两个参数μ和σ2的[连续型随机变量](https://baike.baidu.com/item/%E8%BF%9E%E7%BB%AD%E5%9E%8B%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F)的分布,第一参数μ是服从正态分布的随机变量的[均值](https://baike.baidu.com/item/%E5%9D%87%E5%80%BC),第二个参数σ2是此随机变量的方差,所以正态分布记作N(μ,σ2)。
μ是正态分布的位置参数,描述正态分布的集中趋势位置。概率规律为取与μ邻近的值的概率大,而取离μ越远的值的概率越小。正态分布以X=μ为对称轴,左右完全对称。正态分布的期望、均数、中位数、众数相同,均等于μ。
σ描述正态分布资料数据分布的离散程度,σ越大,数据分布越分散,σ越小,数据分布越集中。也称为是正态分布的形状参数,σ越大,曲线越扁平,反之,σ越小,曲线越瘦高。
标准正态分布:平均值(数学期望μ)是0, 方差(σ^2)是1的正态分布叫做标准正态分布.
【参数】和numpy.zeros/ones一样,接收一个指定的数组,来指定输出的size格式;如果没有提供参数,则返回从分布中随机抽样的单个浮点数。
np.random.randn(3,4,5)
>>array([[[ 0.66424704, -0.19514256, 1.02425611, -1.23709258,
-0.87879702],
[ 1.16202315, -1.61575963, -0.7356401 , -0.31506787,
-1.45950603],
[ 0.56101125, 1.33159725, -0.20095298, 0.84054708,
1.88426501],
[-1.40326522, -1.33462433, 0.42838806, -1.16425388,
0.65539476]],
[[ 2.05200437, -0.6972495 , 0.49552311, -1.00593698,
0.96313528],
[-1.54081464, -0.15111238, 0.40681246, 1.46048705,
1.42382973],
[ 0.04874492, -1.13988598, -1.29158572, 0.95451398,
-1.18913373],
[ 0.27302385, 1.23472254, 0.17149096, 0.47583938,
-0.32925636]],
[[ 0.08109587, -1.29884739, -0.4933034 , 0.38932582,
0.79549131],
[-0.81520021, -1.00687903, 0.45730349, 0.27392281,
-0.0506225 ],
[ 1.88393419, -1.20160838, 1.04152349, -1.09977451,
-0.40580782],
[-1.51162507, 2.05445628, 1.32769429, 0.61975124,
1.29164642]]])
9)np.random.normal(loc=0.0, scale=1.0, size=None)
【意义】从参数化的正态(高斯)分布(给定平均值和标准偏差)中随机抽取样本
【参数】loc:指正态分布的平均值;scale:指标准偏差;size:返回数组的样式
n = np.random.normal(loc=10, scale=3, size=(10000, 300))
>>n
>>array([[10.12461818, 6.64622366, 11.61717496, ..., 8.10664395,
12.36717895, 5.13497859],
[ 5.16850222, 11.49981929, 7.49645438, ..., 9.76567799,
6.76378153, 9.97305511],
[10.007078 , 12.11725761, 12.29760238, ..., 12.4926356 ,
9.11077429, 11.7560803 ],
...,
[ 6.40632836, 13.26634712, 8.70144452, ..., 7.59778943,
7.49250857, 7.33167974],
[13.90225662, 9.92589734, 13.74905492, ..., 9.13568949,
6.37837082, 10.17310031],
[12.63634218, 8.41491648, 14.2450676 , ..., 15.2757429 ,
7.79620393, 17.24517542]])
返回沿给定轴的平均值
n.mean()
>>9.997428945409853
返回沿给定轴的标准差
n.std()
>>3.00011554543728
- np.random.random(size=None)
【意义】生成0.0到1.0的随机数,左闭右开
【参数】返回的array的size格式
np.random.rand(2,3,4)
>>array([[[0.26020732, 0.47964862, 0.83705695, 0.33008704],
[0.79864291, 0.68712366, 0.67892487, 0.68878952],
[0.77980386, 0.7703679 , 0.66518554, 0.99005439]],
[[0.57676182, 0.00750584, 0.50483337, 0.92556118],
[0.8048644 , 0.37534337, 0.5731217 , 0.87761402],
[0.80068917, 0.54915089, 0.72753081, 0.12481967]]])
11)np.random.rand(d0, d1, …, dn)
# 生成0到1之间的随机数, 左闭右开,不包括1
np.random.rand(2,3,4)
3、ndarray的属性
4个必记参数:
ndim:维度
shape:形状(各维度的长度)
size:总长度
dtype:元素类型
n
>>array([[10.12461818, 6.64622366, 11.61717496, ..., 8.10664395,
12.36717895, 5.13497859],
[ 5.16850222, 11.49981929, 7.49645438, ..., 9.76567799,
6.76378153, 9.97305511],
[10.007078 , 12.11725761, 12.29760238, ..., 12.4926356 ,
9.11077429, 11.7560803 ],
...,
[ 6.40632836, 13.26634712, 8.70144452, ..., 7.59778943,
7.49250857, 7.33167974],
[13.90225662, 9.92589734, 13.74905492, ..., 9.13568949,
6.37837082, 10.17310031],
[12.63634218, 8.41491648, 14.2450676 , ..., 15.2757429 ,
7.79620393, 17.24517542]])
n.ndim
>>2
n.shape
>>(10000, 300)
n.size
>>3000000
n.dtype
dtype('float64')
五、ndarray的基本操作
1. 索引-元素索引
一维与列表完全一致 多维时同理
例1:一维数组
l = [1,2,3,4,5]
l[2]
>>3
n = np.array(l)
n
>>array([1, 2, 3, 4, 5])
n[2]
>>3
多维时,array数组可以简写:n[2,2]
例2:多维数组
l = [[1,2,3], [2,3,4], [4,5,6]]
l[2][2]
>>61, 2, 3], [2, 3, 4], [4, 5, 6]]
l[2,2]
>>报错:TypeError: list indices must be integers or slices, not tuple
n = np.array(l)
n
>>array([[1, 2, 3],
[2, 3, 4],
[4, 5, 6]])
n[2][2]
>>6
n[2,2]
>>6
例3:根据索引修改数据
n =np.random.randint(0,100, size=(3,4,5))
n
>>array([[[56, 45, 89, 67, 79],
[95, 62, 50, 5, 93],
[32, 97, 13, 96, 78],
[48, 10, 8, 43, 24]],
[[94, 61, 71, 51, 41],
[77, 26, 39, 79, 46],
[86, 20, 11, 96, 85],
[70, 57, 78, 86, 23]],
[[76, 26, 64, 35, 83],
[32, 5, 42, 90, 7],
[23, 29, 23, 10, 32],
[22, 50, 30, 3, 95]]])
n[1,3,2]第#索取三维中的第2个数据、第二维中的第4个数据、第三维中的第3个数据
>>78
n[1,3,2] = 88#修改上面查询的数据为88
n
>>array([[[56, 45, 89, 67, 79],
[95, 62, 50, 5, 93],
[32, 97, 13, 96, 78],
[48, 10, 8, 43, 24]],
[[94, 61, 71, 51, 41],
[77, 26, 39, 79, 46],
[86, 20, 11, 96, 85],
[70, 57, 88, 86, 23]],
[[76, 26, 64, 35, 83],
[32, 5, 42, 90, 7],
[23, 29, 23, 10, 32],
[22, 50, 30, 3, 95]]])
2. 索引-切片
一维与列表完全一致 多维时同理
例1:一维
l = [1,2,3,4,5,6]
l[1:5]切片是左闭右开
>>[2, 3, 4, 5]
n = np.array(l)
n
>>array([1, 2, 3, 4, 5, 6])
n[1:5]
>>array([2, 3, 4, 5])
例2:多维
n =np.random.randint(0,100, size=(3,4,5))
n
>>array([[[38, 91, 93, 99, 71],
[86, 40, 19, 9, 54],
[32, 35, 76, 47, 49],
[97, 84, 63, 2, 90]],
[[55, 49, 53, 55, 97],
[20, 56, 87, 87, 75],
[22, 19, 60, 80, 4],
[13, 45, 21, 46, 46]],
[[55, 68, 64, 37, 79],
[98, 64, 17, 49, 92],
[66, 32, 19, 55, 81],
[25, 56, 47, 22, 55]]])
n[1:, 1:3, 1:4]
>>array([[[56, 87, 87],
[19, 60, 80]],
[[64, 17, 49],
[32, 19, 55]]])
3. 高级索引-数组索引
3.1 一维数组索引
#一维数组索引,索引值是下标,超出报错
n = np.arange(10,1,-1)
n
>>array([10, 9, 8, 7, 6, 5, 4, 3, 2])
n[np.array([3,3,1,8])]
#n[[3,3,1,8]]#可简写
array([7, 7, 9, 2])
3.2 多维数组索引
#多维数组索引,索引值是当前维度的下标
y = np.arange(35).reshape(5,7)
y
>>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, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
y[np.array([0,2,3,4])]#当前维度是二维,下标有0,1,2,3,4
>>array([[ 0, 1, 2, 3, 4, 5, 6],
[14, 15, 16, 17, 18, 19, 20],
[21, 22, 23, 24, 25, 26, 27],
[28, 29, 30, 31, 32, 33, 34]])
y[np.array([0,2,3,4]), np.array([0,1,2,5])]
#得到一维后,第二个np.array相当于对一维取元素,每个位置对应一个一维数组,根据数据对应去取对应的元素
#取到的结果等同域
>>array([ 0, 15, 23, 33])
y[np.array([0,2,4]), 1]
#广播机制允许索引数组与其他索引的标量组合。结果是标量值用于索引数组的所有相应值
>>array([ 1, 15, 29])
4.将数据反转
例如[1,2,3]---->[3,2,1]
l = [1, 2, 3, 4, 5, 6]
l[::-1]
>>[6, 5, 4, 3, 2, 1]
s = 'abcdef'
s[::-1]
'fedcba'>>
import matplotlib.pyplot as plt
%matplotlib inline
cat = plt.imread('./cat.jpg')#cat是一张猫咪图片
cat#得到的是一系列RGB组成的数组,入下shape
#cat.shape
#>>(456, 730, 3)
plt.figure(figsize=(10,8))#调整图片大小
plt.imshow(cat)#展示图片
>><matplotlib.image.AxesImage at 0x1bf7f72fda0>+调整尺寸后的猫咪图片
plt.figure(figsize=(10,8))
plt.imshow(cat[::-1])#相当于在图片高度方向正中间水平画了一条线,上下翻转调换,得到的是一张上下倒置的图片
plt.figure(figsize=(10,8))
plt.imshow(cat[:, ::-1])#相当于在图片水平方向正中间垂直画了一条线,左右翻转调换,得到的是一张左右调换的图片
plt.figure(figsize=(10,8))
plt.imshow(cat[::-1, ::-1])#同时进行上下、左右的调换
plt.figure(figsize=(10,8))
plt.imshow(cat[:, :, ::-1])#对图片颜色进行调换
两个::进行切片
5. 变形
使用reshape函数,注意参数是一个tuple!
reshape的关键就在于,总元素个数不能发生变化.
#原型
n =np.random.randint(0,100, size=(3,4,5))
n
>>array([[[ 9, 90, 13, 95, 28],
[ 6, 68, 79, 26, 78],
[25, 28, 57, 52, 8],
[62, 15, 33, 19, 60]],
[[82, 81, 30, 75, 4],
[44, 3, 14, 53, 57],
[30, 32, 9, 17, 33],
[53, 41, 70, 87, 69]],
[[ 7, 33, 32, 21, 87],
[43, 9, 95, 63, 15],
[41, 35, 71, 62, 14],
[23, 29, 72, 49, 84]]])
#变换,使用array对象直接操作
n.reshape((5, 12))#只要内部元素数目一样多,可以进行任意的变换,新数组元素按原数组中的顺序提取
>>array([[ 9, 90, 13, 95, 28, 6, 68, 79, 26, 78, 25, 28],
[57, 52, 8, 62, 15, 33, 19, 60, 82, 81, 30, 75],
[ 4, 44, 3, 14, 53, 57, 30, 32, 9, 17, 33, 53],
[41, 70, 87, 69, 7, 33, 32, 21, 87, 43, 9, 95],
[63, 15, 41, 35, 71, 62, 14, 23, 29, 72, 49, 84]])
n.reshape(5,12)#元组的括号可以取消,结果一致
#使用np数组对象进行操作,结果是一致的
np.reshape(n, newshape=(5,12))
array([[ 9, 90, 13, 95, 28, 6, 68, 79, 26, 78, 25, 28],
[57, 52, 8, 62, 15, 33, 19, 60, 82, 81, 30, 75],
[ 4, 44, 3, 14, 53, 57, 30, 32, 9, 17, 33, 53],
[41, 70, 87, 69, 7, 33, 32, 21, 87, 43, 9, 95],
[63, 15, 41, 35, 71, 62, 14, 23, 29, 72, 49, 84]])
#转换成指定格式的数组,可不准确计算,添加计算公式即可
n.reshape(3,4*5)
>>array([[ 9, 90, 13, 95, 28, 6, 68, 79, 26, 78, 25, 28, 57, 52, 8, 62,
15, 33, 19, 60],
[82, 81, 30, 75, 4, 44, 3, 14, 53, 57, 30, 32, 9, 17, 33, 53,
41, 70, 87, 69],
[ 7, 33, 32, 21, 87, 43, 9, 95, 63, 15, 41, 35, 71, 62, 14, 23,
29, 72, 49, 84]])
n.reshape(4, -1)#自动将所有元素(m)划分成若干组(n),前提条件是n可以被m整除,否则报错,n后面的参数为负数即可。此处是将其分成3组:
>>array([[ 9, 90, 13, 95, 28, 6, 68, 79, 26, 78, 25, 28, 57, 52,8],
[62, 15, 33, 19, 60, 82, 81, 30, 75, 4, 44, 3, 14, 53, 57],
[30, 32, 9, 17, 33, 53, 41, 70, 87, 69, 7, 33, 32, 21, 87],
[43, 9, 95, 63, 15, 41, 35, 71, 62, 14, 23, 29, 72, 49, 84]])
reshape(-1,1)#将元素变成只有1行的数组
6. 级联
6.1 np.concatenate()
np.concatenate() 级联需要注意的点:
- 级联的参数是列表:一定要加中括号或小括号
- 维度必须相同
- 形状相符
- 【重点】级联的方向默认是shape这个tuple的第一个值所代表的维度方向
- 可通过axis参数改变级联的方向
n1 = np.random.randint(0,100, size=(3,4))
n2 = np.random.randint(0,100, size=(3,4))
display(n1, n2)
>>array([[60, 98, 22, 16],
[ 2, 91, 60, 10],
[39, 7, 14, 77]])
array([[61, 22, 39, 60],
[48, 43, 89, 70],
[73, 48, 90, 1]])
# 水平级联 axis=1,水平级联要求行数一致
np.concatenate((n1,n2), axis=1)
>>array([[60, 98, 22, 16, 61, 22, 39, 60],
[ 2, 91, 60, 10, 48, 43, 89, 70],
[39, 7, 14, 77, 73, 48, 90, 1]])
# 垂直级联 , axis=0, 要求列数一致
np.concatenate((n1,n2), axis=0)
array([[60, 98, 22, 16],
[ 2, 91, 60, 10],
[39, 7, 14, 77],
[61, 22, 39, 60],
[48, 43, 89, 70],
[73, 48, 90, 1]])
6.2 np.hstack与np.vstack
水平级联与垂直级联,处理自己,进行维度的变更
# h = horizontal 水平(水平方向拓展级联)
# v = vertical 垂直(垂直方向拓展级联)
np.hstack((n1,n2))
>>array([[60, 98, 22, 16, 61, 22, 39, 60],
[ 2, 91, 60, 10, 48, 43, 89, 70],
[39, 7, 14, 77, 73, 48, 90, 1]])
np.vstack((n1, n2))
>>array([[60, 98, 22, 16],
[ 2, 91, 60, 10],
[39, 7, 14, 77],
[61, 22, 39, 60],
[48, 43, 89, 70],
[73, 48, 90, 1]])
7. 切分
与级联类似,三个函数完成切分工作:
- np.split
np.split(ary, indices_or_sections, axis=0)
ary:array数组
indices_or_sections:索引或截取区间
axis:切割轴线,默认为0,切割的是行
- np.vsplit
垂直方向下刀切割,即按行切割 - np.hsplit
水平方向下刀切割,即按列切割
#array原型数组
n = np.random.randint(0, 100, size=(6,6))
n
>>array([[35, 88, 77, 45, 59, 33],
[94, 22, 84, 54, 53, 44],
[16, 9, 93, 44, 83, 56],
[80, 28, 93, 51, 69, 46],
[27, 39, 33, 47, 94, 17],
[97, 92, 49, 83, 7, 39]])
7.1 原生split
# 垂直方向下刀,切的是行 ,axis=0
#分成三个数组返回:切割位置前、切割位置、切割位置后
np.split(n, [1,3], axis=0)
>>[array([[35, 88, 77, 45, 59, 33]]), array([[94, 22, 84, 54, 53, 44],
[16, 9, 93, 44, 83, 56]]), array([[80, 28, 93, 51, 69, 46],
[27, 39, 33, 47, 94, 17],
[97, 92, 49, 83, 7, 39]])]
# 水平方向下刀,切的是列 ,axis=1
#分成三个数组返回:切割位置前、切割位置、切割位置后
np.split(n, [1,3], axis=1)
>>[array([[35],
[94],
[16],
[80],
[27],
[97]]), array([[88, 77],
[22, 84],
[ 9, 93],
[28, 93],
[39, 33],
[92, 49]]), array([[45, 59, 33],
[54, 53, 44],
[44, 83, 56],
[51, 69, 46],
[47, 94, 17],
[83, 7, 39]])]
7.2 封装的vsplit、hsplit
np.vsplit(n, [1,3])
>>[array([[35, 88, 77, 45, 59, 33]]), array([[94, 22, 84, 54, 53, 44],
[16, 9, 93, 44, 83, 56]]), array([[80, 28, 93, 51, 69, 46],
[27, 39, 33, 47, 94, 17],
[97, 92, 49, 83, 7, 39]])]
np.hsplit(n, [1,3])
>>[array([[35],
[94],
[16],
[80],
[27],
[97]]), array([[88, 77],
[22, 84],
[ 9, 93],
[28, 93],
[39, 33],
[92, 49]]), array([[45, 59, 33],
[54, 53, 44],
[44, 83, 56],
[51, 69, 46],
[47, 94, 17],
[83, 7, 39]])]
8. 副本
8.1 赋值创建副本
所有赋值运算不会为ndarray的任何元素创建副本。对赋值后的对象的操作也对原来的对象生效。相当于Python中的赋值拷贝,操作同一块内存区域。
例:
#原生数组模型
n = np.random.randint(0, 100, size=(6,6))
n
>>array([[41, 61, 40, 38, 67, 78],
[87, 4, 93, 31, 69, 25],
[16, 27, 60, 40, 34, 19],
[85, 52, 22, 24, 89, 66],
[44, 81, 30, 1, 74, 21],
[26, 69, 97, 56, 81, 89]])
n2 = n
n2 is n
>>True
n2[0,0] = 88
n2
>>array([[88, 61, 40, 38, 67, 78],
[87, 4, 93, 31, 69, 25],
[16, 27, 60, 40, 34, 19],
[85, 52, 22, 24, 89, 66],
[44, 81, 30, 1, 74, 21],
[26, 69, 97, 56, 81, 89]])
n
>>array([[88, 61, 40, 38, 67, 78],
[87, 4, 93, 31, 69, 25],
[16, 27, 60, 40, 34, 19],
[85, 52, 22, 24, 89, 66],
[44, 81, 30, 1, 74, 21],
[26, 69, 97, 56, 81, 89]])
8.2 使用copy()函数创建副本
相当于Python中的深拷贝,开辟了一块完全新的内存区域。
n3 = n.copy()
n3 is n
>>False
n3 == n
>>array([[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True],
[ True, True, True, True, True, True]])
n3[0,0] = 99
n3
>>array([[99, 77, 22, 93, 99, 42],
[63, 77, 20, 51, 30, 52],
[50, 73, 42, 89, 28, 27],
[75, 63, 38, 60, 11, 48],
[ 7, 10, 56, 87, 81, 17],
[79, 38, 63, 60, 26, 5]])
n
>>array([[88, 77, 22, 93, 99, 42],
[63, 77, 20, 51, 30, 52],
[50, 73, 42, 89, 28, 27],
[75, 63, 38, 60, 11, 48],
[ 7, 10, 56, 87, 81, 17],
[79, 38, 63, 60, 26, 5]])
9. 查找ndarray数据索引
labels
>>array([0, 1, 1, 2, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0])
#查找为0的元素,并扁平化展示
np.argwhere(labels==0).ravel()
>>array([ 0, 5, 6, 7, 9, 10, 11, 14], dtype=int64)
六、ndarray的聚合操作
#原生数组模型
n = np.random.randint(0, 100, size=(6,6))
n
>>array([[88, 61, 40, 38, 67, 78],
[87, 4, 93, 31, 69, 25],
[16, 27, 60, 40, 34, 19],
[85, 52, 22, 24, 89, 66],
[44, 81, 30, 1, 74, 21],
[26, 69, 97, 56, 81, 89]])
1. 求和np.sum
1.1 数组整体求和
#对象求和
np.sum(n)
>>1884
#数组直接求和
n.sum()
>>1884
1.2 数组按列/按行求和
例1:二维数组
n = np.random.randint(0,100, size=(3,5))
n
>>array([[27, 80, 52, 32, 82],
[55, 13, 18, 21, 98],
[57, 18, 17, 54, 88]])
# axis=1表示对列进行聚合操作.列没了,行还在. 求每一行的和
n.sum(axis=1)
>>array([273, 205, 234])
# 求每一列的和
n.sum(axis=0)
>>array([168, 110, 138, 164, 131])
例2:多维数组
n = np.random.randint(0,100, size=(3,4,5))
n
>>array([[[48, 16, 1, 10, 2],
[ 1, 58, 92, 58, 77],
[54, 45, 59, 0, 49],
[86, 89, 44, 88, 68]],
[[62, 98, 63, 70, 57],
[39, 56, 34, 64, 3],
[36, 52, 91, 49, 25],
[29, 25, 24, 57, 79]],
[[11, 73, 18, 73, 57],
[ 2, 95, 55, 88, 99],
[ 3, 75, 66, 54, 42],
[36, 43, 13, 29, 69]]])
#对多维数组的每个子数组进行求和操作,相当于对行进行聚合,每个子数组列的对应重叠位置进行相加
n.sum(axis=0)
>>array([[121, 187, 82, 153, 116],
[ 42, 209, 181, 210, 179],
[ 93, 172, 216, 103, 116],
[151, 157, 81, 174, 216]])
#对多维子数组的列进行聚合,每个子数组变成各行聚合变成一行
n.sum(axis=1)
array([[189, 208, 196, 156, 196],
[166, 231, 212, 240, 164],
[ 52, 286, 152, 244, 267]])
2. 最大最小值:np.max/ np.min
#以上述二维数组为例
n.max()
>>98
n.min
>>13
n.max(axis=0)
>>array([57, 80, 52, 54, 98])
n.max(axis=1)
>>array([82, 98, 88])
3. 其他聚合操作
Function Name NaN-safe Version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.argmin np.nanargmin Find index of minimum value
np.argmax np.nanargmax Find index of maximum value
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true
np.power 幂运算
3.1 nan
np.nan # 对应python中的None
>>nan
n = np.array([1,2,3,np.nan])
n
>>array([ 1., 2., 3., nan])
n.sum
>>nan#不可求和
np.sum和np.nansum的区别:
np.sum(n)
>>nan
np.nansum(n)#将nan视为0进行聚合运算
>>6
3.2 any和all
l = [1,2,0]
# 只有有一个True,就返回True
any(l)
np.any(l)
>>True
l = [1,2,1]
all(l) # 所有的都是True才返回True
np.all(l)
>>True
3.3 返回沿给定轴的平均值
n.mean()
>>9.997428945409853
3.4 返回沿给定轴的标准差
n.std()
>>3.00011554543728
- np.random.random(size=None)
七、ndarray的矩阵操作(运算)
1. 基本矩阵操作
1.1 算术运算符:
与数进行加减乘除,各元素与该数一一进行加减乘除
#原生数组示例
n = np.random.randint(0,100,size=(3,5))
n
>>array([[24, 80, 30, 57, 99],
[75, 27, 21, 37, 49],
[28, 88, 89, 50, 18]])
n + 1
>>array([[ 25, 81, 31, 58, 100],
[ 76, 28, 22, 38, 50],
[ 29, 89, 90, 51, 19]])
n-1
>>array([[23, 79, 29, 56, 98],
[74, 26, 20, 36, 48],
[27, 87, 88, 49, 17]])
n*2
>>array([[ 48, 160, 60, 114, 198],
[150, 54, 42, 74, 98],
[ 56, 176, 178, 100, 36]])
n/2
>>array([[12. , 40. , 15. , 28.5, 49.5],
[37.5, 13.5, 10.5, 18.5, 24.5],
[14. , 44. , 44.5, 25. , 9. ]])
数组间的运算
#原生数组示例
n1 = np.random.randint(0,10, size=(3,4))
n2 = np.random.randint(0,10, size=(3,4))
display(n1,n2)
>>array([[1, 4, 6, 1],
[3, 0, 8, 7],
[9, 1, 6, 3]])
array([[6, 6, 1, 7],
[3, 3, 3, 7],
[8, 0, 5, 6]])
n1 + n2 # size格式一致时,相同位置的元素进行运算.
>>array([[ 7, 10, 7, 8],
[ 6, 3, 11, 14],
[17, 1, 11, 9]])
n1 = np.random.randint(0,10, size=(3,4))
n2 = np.random.randint(0,10, size=(2,4))
display(n1,n2)
>>array([[5, 9, 5, 9],
[1, 8, 6, 9],
[2, 6, 2, 4]])
array([[1, 7, 4, 9],
[4, 4, 7, 8]])
n1 + n2 #格式不一样时报错
>>ValueError: operands could not be broadcast together with shapes (3,4) (2,4)
1.2 矩阵积np.dot()
np.dot():第一个矩阵的列数等于第二个矩阵的行数
n1 = np.random.randint(0,100, size=(5,3))
n2 = np.random.randint(0,100, size=(4,2))
display(n1,n2)
>>
array([[79, 0, 87],
[ 7, 67, 45],
[38, 50, 22],
[14, 29, 50],
[27, 30, 27]])
array([[65, 17],
[47, 57],
[41, 92]])
#矩阵乘积
np.dot(n1,n2)
>>
array([[8702, 9347],
[5449, 8078],
[5722, 5520],
[4323, 6491],
[4272, 4653]])S
2. 广播机制
【重要】ndarray广播机制的两条规则
- 规则一:为缺失的维度补1
- 规则二:假定缺失元素用已有值填充
例1: m = np.ones((2, 3)) a = np.arange(3) 求M+a
# numpy使用广播 机制,来让两个运算的ndarray的shape变成一致.
m = np.ones((2,3))
m
>>array([[1., 1., 1.],
[1., 1., 1.]])
a = np.arange(3)
a
>>array([0, 1, 2])
m + a
>>array([[1.,2.,3.],
[1.,2.,3.]])
'''
a缺了一个维度, 广播机制会补一个维度:[[0,1,2]]
补完之后,a缺了数据, 广播机制会使用已有的数据进行填充.
[[0,1,2],
[0,1,2]]
'''
广播机制的两条规则:
1, 缺失维度给你补维度.
2, 缺失数据给你补数据,用已有的数据进行补充.
n1 = np.random.randint(0,10, size=(3,4))
n2 = np.random.randint(0,10, size=(2,4))
display(n1,n2)
>>array([[2, 7, 5, 9],
[4, 3, 6, 0],
[6, 4, 0, 3]])
array([[5, 7, 4, 2],
[8, 6, 3, 3]])
例2: a = np.arange(3).reshape((3, 1)) b = np.arange(3) 求a+b
a = np.arange(3).reshape((3, 1))
b = np.arange(3)
display(a, b)
>>array([[0],
[1],
[2]])
array([0, 1, 2])
a + b
array([[0, 1, 2],
[1, 2, 3],
[2, 3, 4]])
'''
b缺维度.
[[0,1,2]]
a缺数据, 用已有的数据填充.
[[0,0,0], [1,1,1,], [2,2,2]]
b缺数据,用已有的数据填充
[[0,1,2], [0,1,2],[0,1,2]]
'''
例3 a = np.ones((4, 1)) b = np.arange(4) 求a+b
a = np.ones((4, 1))
a
>>array([[1.],
[1.],
[1.],
[1.]])
b = np.arange(4)
b
>>array([0, 1, 2, 3])
a + b
array([[1., 2., 3., 4.],
[1., 2., 3., 4.],
[1., 2., 3., 4.],
[1., 2., 3., 4.]])
例4 无法操作的例子
n1 = np.random.randint(0,10, size=(3,4))
n2 = np.random.randint(0,10, size=(2,4))
display(n1,n2)
>>array([[5, 9, 5, 9],
[1, 8, 6, 9],
[2, 6, 2, 4]])
array([[1, 7, 4, 9],
[4, 4, 7, 8]])
n1 + n2 #格式不一样时报错
>>ValueError: operands could not be broadcast together with shapes (3,4) (2,4)
没有数组缺维度,n2数组缺数据,但是已存在两行数据,无法确定填充数据,广播机制不起作用