python数据分析之NumPy详解

一、NumPy介绍

NumPy(Numerical Python)是Python的一个开源数值计算库。可用来存储和处理大型矩阵,比python自身的嵌套列表结构要高效得多,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库,包括数学、逻辑、形状操作、排序、选择、输入输出、离散傅里叶变换、基本线性代数、基本统计运算和随机模拟等等。
几乎所有从事python工作的数据分析师都利用NumPy的强大功能

二、创建ndarray

ndarray是NumPy中表示数组的重要类型(nd表示n个维度)。比如图像数据的表示就是一个三维数组,图像通常由像素组成,每一个像素可以有一个或多个通道(Channel),用于表示颜色或深度信息:

  • 第一个维度(高度):图像的行数
  • 第二个维度(宽度):图像的列数
  • 第三个维度(通道):图像的颜色通道数

例如:

  • 对于灰度图像,只有一个通道,因此可以表示为一个二维数组
  • 对于彩色图像(如RGB图像),通常有三个通道(红、绿、蓝),因此可以表示为一个三维数组。

1、使用np.array()创建

import numpy as np
n = np.array([1,2,3,4])
print(n)
print(type(n)) # 类型
print(n.shape) # 形状,一维数组就是一个元组来表示
[1 2 3 4]
<class 'numpy.ndarray'>
(4,)

注意:

  • numpy默认ndarry的所有元素类型是相同的
  • 如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str>float>int
  • ndarry的常见的数据类型:
    • int:int8、uint8、int16、int32、int64
    • float:float16、float32、float64
    • str:字符串
import numpy as np
n = np.array([3.14,2,"haha"])
n
array(['3.14', '2', 'haha'], dtype='<U32')

2、使用np的routines函数创建

1)np.ones(shape,dtype=None,order=“C”)

  • 创建一个所有元素都为1的数组
    参数说明:
  • shape:形状
  • dtype=None:类型
  • order:{‘C’,‘F’},可选,默认值:C是否在内存中以行主(C-风格)或列主(Fortran-风格)顺序存储多维数组,一般默认即可。
import numpy as np
n = np.ones((3,4),dtype=np.int8)
# n = np.ones((3,4),dtype=int)
n
array([[1, 1, 1, 1],
       [1, 1, 1, 1],
       [1, 1, 1, 1]], dtype=int8)

1)np.zeros(shape,dtype=float,order=‘C’)

  • 创建一个所有元素都为0的多维数组
import numpy as np
n = np.zeros((3,4),dtype=int)
n
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

3)np.full(shape,fill_value,dtype=None,order=‘C’)

  • 创建一个所有元素都为指定元素的多维数组,其中fill_value表示填充值。
import numpy as np
n = np.full((3,4),fill_value=6,dtype=int)
n
array([[6, 6, 6, 6],
       [6, 6, 6, 6],
       [6, 6, 6, 6]])

4)np.eye(N,M=None,k=0,dtype=int)

  • 对角线为1其他位置为0的二维数组(单位矩阵)

参数说明:

  • N:行数
  • M:列数
  • k=0:向右偏移0个位置
import numpy as np
n = np.eye(6,k=1,dtype=int)
# 如果M不指定默认与N有相同行数
n
array([[0, 1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0],
       [0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1],
       [0, 0, 0, 0, 0, 0]])

5)np.linspace(start,stop,num=50,endpoint=True,retstep=False,dtype=None)

  • 创建一个等差数列

参数说明:

  • start:开始值
  • stop:结束值
  • num=50:等差数列中默认有50个值
  • endpoint:是否包含结束值
  • retstep:是否返回等差值(步长哪个)
import numpy as np
n = np.linspace(0,100,num=51,endpoint=False,retstep=True)
n
(array([ 0.        ,  1.96078431,  3.92156863,  5.88235294,  7.84313725,
         9.80392157, 11.76470588, 13.7254902 , 15.68627451, 17.64705882,
        19.60784314, 21.56862745, 23.52941176, 25.49019608, 27.45098039,
        29.41176471, 31.37254902, 33.33333333, 35.29411765, 37.25490196,
        39.21568627, 41.17647059, 43.1372549 , 45.09803922, 47.05882353,
        49.01960784, 50.98039216, 52.94117647, 54.90196078, 56.8627451 ,
        58.82352941, 60.78431373, 62.74509804, 64.70588235, 66.66666667,
        68.62745098, 70.58823529, 72.54901961, 74.50980392, 76.47058824,
        78.43137255, 80.39215686, 82.35294118, 84.31372549, 86.2745098 ,
        88.23529412, 90.19607843, 92.15686275, 94.11764706, 96.07843137,
        98.03921569]),
 1.9607843137254901)

6)np.arange([start,]stop,[step,]dtype=None)

  • 创建一个数值范围数组
  • 与python中的range函数功能类似

参数说明:

  • start:开始值(可选)
  • stop:结束值(不包含)
  • step:步长哪个(可选)
import numpy as np
n = np.arange(2,10,2)
n
array([2, 4, 6, 8])

7)np.random.randint(low,high=None,size=None,dtype=None)

  • 创建一个随机整数的多维数组

参数说明:

  • low:最小值
  • high:最大值
    • high=None时,生成的数值在[0,low]区间内
    • 如果使用high这个值,则生成的数值在[low,high)区间内
  • size:数组形状,默认只输出一个随机值
import numpy as np
n = np.random.randint(0,100,(3,4),dtype=int)
n
array([[65,  2, 28, 98],
       [83, 87, 95, 77],
       [57, 87, 93,  3]])

8)np.random.randn(d0,d1,…,dn)

  • 创建一个服从标准正态分布的数组
标准正态分布又称u分布(高斯分布),是以0为均值,以1为标准差的正态分布,记为x~N(0,1)标准正态分布。在0左右出现的概率最大,越远离出现的概率越低。
  • 创建一个所有元素都为1的多维数组

参数说明:

  • dn:第n个维度的数值
import numpy as np
n = np.random.randn(3,4)
n
array([[-1.16642433,  2.28540892, -0.84647505,  0.70431272],
       [-0.01542117, -1.71755485, -2.06617207,  1.49153731],
       [ 1.48517881,  0.80147185,  0.49214101, -0.0042536 ]])

9)np.random.normal(loc=0.0,scale=1.0,size=None)

  • 创建一个服从正态分布的多维数组

参数说明:

  • loc:均值,对应着正态分布的中心
  • scale:标准差,对应着分布的宽度,scale越大,正态分布的曲线就越矮胖,scale越小,曲线越高瘦。
  • size:数组形状
import numpy as np
n = np.random.normal(loc=100,scale=1,size=(3,4))
n
array([[100.06052885, 101.46798012,  97.93215097,  99.82776279],
       [103.24421836, 101.97041366,  98.88515404,  99.00016403],
       [100.47565086, 101.99688983, 100.22201324, 100.26000772]])

10)np.random.random(size=None)

  • 创建一个元素为0~1(左闭右开)的随机数的多维数组

参数说明:

  • size:数组形状
import numpy as np
n = np.random.random((3,4))
n
array([[0.71567305, 0.41808001, 0.0516382 , 0.09077367],
       [0.24400181, 0.15027429, 0.04032072, 0.8586849 ],
       [0.26922107, 0.98332015, 0.7076481 , 0.98187247]])

11)np.random.rand(d0,d1,…dn)

  • 创建一个元素为0~1(左闭右开)的随机数的多维数组
  • 这与np.random.random()功能相同

三、ndarray的属性

四个重要属性:

  • ndim:维度
  • shape:形状
  • size:总长度
  • dtype:元素类型

四、numpy的基本操作

1、索引操作

一维与列表完全一致,多维时同理

import numpy as np
n = np.random.randint(0,10,size=(3,4))
n,n[1,2] # 也可以这样写:n[1][2]
(array([[6, 8, 4, 7],
        [9, 7, 1, 3],
        [1, 6, 5, 8]]),
 1)

根据索引修改数据

import numpy as np
n = np.random.randint(0,10,size=(3,4))
n[1,2]=120
n
array([[  2,   1,   6,   6],
       [  5,   0, 120,   6],
       [  2,   7,   4,   6]])

2、切片操作

一维与列表完全一致,多维时同理

import numpy as np
n = np.arange(12)
n[2:6],n[::-1] # 将数组翻转
# 连续取多行数据也需要用到切片操作
import numpy as np
n = np.random.randint(0,10,size=(6,6))
n[1:4]
# 取不连续的多行
n[[1,2,4]]
# 取列
n[:,0]
# 取连续的多列:切片
n[2:5:,1:4]
# 取不连续的多列
n[:,[1,2,4]]
array([[2, 7, 9],
       [6, 4, 0],
       [6, 1, 4],
       [5, 5, 4],
       [5, 1, 6],
       [8, 8, 4]])

3、变形操作

使用reshape函数

import numpy as np
n = np.arange(12).reshape(3,4)
# 使用-1来表示剩余维度
n1 = np.arange(12).reshape(3,-1)
n,n1
(array([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]]),
 array([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]]))

4、级联操作

np.concatenate()

  • 参数必须是列表或元组
  • 级联的数组维度必须相同
  • 可以通过参数axis改变级联的方向
import numpy as np
n1 = np.random.randint(0,100,size=(3,4))
n2 = np.random.randint(0,10,size=(3,4))
n = np.concatenate((n1,n2),axis=1)
n
array([[10, 57, 10, 54,  7,  9,  5,  2],
       [83, 75,  2, 90,  0,  8,  8,  2],
       [62, 64, 49, 97,  8,  3,  8,  5]])

np.hsrack与np.vstack

  • 水平级联与垂直级联(功能与np.concatenate函数功能相同,只需要掌握一个就好)
import numpy as np
n1 = np.random.randint(0,100,size=(3,4))
n2 = np.random.randint(0,50,size=(3,4))
# 水平级联
n3 = np.hstack((n1,n2))
# 垂直级联
n4 = np.vstack((n1,n2))
n3,n4
(array([[41, 38, 92, 85, 44, 47, 30,  1],
        [23, 29, 58, 34, 46, 30, 36, 36],
        [97, 91,  7, 90, 26,  3,  9, 39]]),
 array([[41, 38, 92, 85],
        [23, 29, 58, 34],
        [97, 91,  7, 90],
        [44, 47, 30,  1],
        [46, 30, 36, 36],
        [26,  3,  9, 39]]))

5、拆分操作

与级联类似,三个函数完成切分工作

  • np.split
  • np.vsplit
  • np.hsplit
    np.split函数的功能与np.vsplit、np.hsplit函数功能类似,掌握一个即可
import numpy as np
n = np.random.randint(0,100,size=(6,4))
np.split(n,3,axis=0)
# 也可以根据位置索引来进行拆分
np.split(n,(1,2,4),axis=0)
[array([[87, 70, 57, 89]]),
 array([[38, 90, 49, 12]]),
 array([[ 5, 22, 29, 84],
        [40, 86, 43, 88]]),
 array([[ 5,  6, 50, 21],
        [17, 93, 82, 12]])]

6、副本/复制/拷贝

拷贝是原数据的一个完整副本,他不共享数据块。修改拷贝中的数据不会影响到原数组,反之亦然。创建拷贝会占用额外的内存。

  • copy()函数创建副本
import numpy as np
n = np.arange(10)
n1 = n
n[0]=10
display(n,n1) # 这就会导致n与n1共用同一块内存,赋值操作会把两个之都修改
# 拷贝操作
n2 = n.copy()
n2[0] = 1
display(n2,n)
array([10,  1,  2,  3,  4,  5,  6,  7,  8,  9])

array([10,  1,  2,  3,  4,  5,  6,  7,  8,  9])

array([1, 1, 2, 3, 4, 5, 6, 7, 8, 9])

array([10,  1,  2,  3,  4,  5,  6,  7,  8,  9])

五、ndarrry的聚合操作

  • np.sum 求和
  • np.min 求最小值
  • np.max 求最大值
  • np.mean 求平均值
  • np.average 求平均值
  • np.median 求中位数
  • np.percentile 求百分位数
  • np.argmin 求最小值对应的下标
  • np.argmax 求最大值对应的下标
  • np.std 求标准差
  • np.var 求方差
  • np.power 求次幂
  • np.argwhere 按条件查找
import numpy as np
a = np.arange(12).reshape(3,4)
sum_a= np.sum(a1,axis=0) #沿着行方向求和:即每一列的和,如果没有axis参数则代表求所有和
# 结果为:array([12, 15, 18, 21])
max_a = np.max(a) # 结果为11
# 若是数组中有控制的存在,直接用sum是求不出来的,可以用np.nansum函数求
b = np.array([1,2,3,np.nan])
np.nansum(b) # 排除掉nan之后的所有数据之和
# 求平均值
average_a = np.mean(a) # 结果为:5.5,也可以这样写:np.average(a)
# 求中位数
median_a = np.median(a,axis=0) # 结果为array([4., 5., 6., 7.])
# 求百分位数
percentile_a = np.percentile(a,q=50)# 结果为:5.5,q=50表示中位数
# 求最大值对应的下标
a = a.reshape(-1)
display(a)
max_index = np.argmax(a)
# 求最小值对应的下标
min_index = np.argmin(a)
# 但这样会出现一个问题,就是argmax与argmin只会找到第一个与之匹配的下标,对于重复的元素却无法检测出。我们可以用argwhere的方法
np.argwhere(a==np.max(a))
# 求次幂
power_a = np.power(a,3) # 结果为:array([   0,    1,    8,   27,   64,  125,  216,  343,  512,  729, 1000, 1331], dtype=int32)
# 也可以直接这样写:a**3
# 求标准差
std_a = np.std(a)
# 求方差
var_a = np.var(a)
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

类似于上述的聚合函数还有很多,这里仅给出比较常用的几个,剩下的就不一一列举了。

六、NumPy的矩阵操作

1、基本矩阵操作

1)算数运算符:

  • 加减乘除
import numpy as np
n = np.random.randint(0,10,size=(4,5))
display(n)
# 加法运算
n + 10
# 减法运算
n - 10
# 乘法运算
n * 10
# 除法运算
n / 10
# 整除运算
n // 2
# 取余运算
n % 2
array([[7, 9, 6, 8, 8],
       [4, 9, 9, 6, 5],
       [0, 3, 4, 3, 8],
       [1, 2, 5, 5, 2]])

array([[1, 1, 0, 0, 0],
       [0, 1, 1, 0, 1],
       [0, 1, 0, 1, 0],
       [1, 0, 1, 1, 0]], dtype=int32)

两个矩阵之间同样可以用来做运算。

import numpy as np
n1 = np.random.randint(0,10,size=(4,5))
n2 = np.random.randint(0,10,size=(4,5))
n1 + n2 # 对应元素相加
n1 * n2 # 对应元素元素相乘
array([[ 3, 32, 27, 35, 24],
       [ 2,  3,  3, 21, 63],
       [27, 16, 45, 32, 21],
       [45, 18,  0, 63, 81]])

2)线性代数

  • 矩阵积运算np.dot(),这里需要满足一个条件:第一个矩阵的列数等于第二个矩阵的行数才能进行运算
import numpy as np
n1 = np.random.randint(0,10,size=(4,5))
n2 = np.random.randint(0,10,size=(5,4))
np.dot(n1,n2) #也可直接n1 @ n2
array([[139,  52, 152,  52],
       [110,  55, 131,  34],
       [107,  52,  98,  49],
       [126,  56, 147,  50]])
  • 线性代数中其他矩阵操作:求逆矩阵、求矩阵转置、求矩阵的秩等
import numpy as np
n = np.array([[1,2,3],[2,5,4],[4,5,6]])
# 求矩阵的逆
np.linalg.inv(n)
# 求矩阵的行列式
np.linalg.det(n)
# 求矩阵的秩
np.linalg.matrix_rank(n)
3

2、广播机制

NumPy的广播机制是一种强大的功能,它允许不同形状的数组进行算术运算。广播机制通过自动扩展较小的数组来匹配较大数组的形状,从而使得逐元素操作成为可能。
广播规则:

  • 形状对齐:从最右边的维度开始,比较两个数组的形状。如果两个数组维度大小相等,或者其中一个数组的维度大小为1,则这两个数组在该维度上是兼容的。
  • 扩展维度:如果其中一个数组在某个维度上的大小为1,而另一个数组在该维度上的大小大于1,则大小为1的数组会在该维度上扩展一匹配另一个数组的大小。
  • 不兼容情况:如果在某个维度上,两个数组的大小都不为1且不相等,则这两个数组在改为都上是不兼容的,无法进行广播。

让我们通过一个例子来说明广播机制:

import numpy as np
a = np.ones((2,3),dtype=int)
b = np.arange(3)
a+b
array([[1, 2, 3],
       [1, 2, 3]])

3、其他常见数学操作

  • abs、aqrt、square、exp、log、sin、cos、tan、round、ceil、floor、cumsum
import numpy as np
n = np.array([1,4,7,8,9],dtype=int)
# 求绝对值
abs_n = np.abs(n)
# 求平方跟
sqrt_n = np.sqrt(n)
# 求平方
square_n = np.square(n)
# 指数运算
exp_n = np.exp(n)
# 对数运算
ln_n = np.log(n) # 以e为底n的对数
log_n = np.log10(n) # 以10为底,n的对数
# 三角函数运算
sin_n = np.sin(n)
# 四舍五入
round_n = np.round(n)
# 向上取整运算
ceil_n = np.ceil(n)
# 向下取整运算
floor_n = np.floor(n)
# 累加运算
cumsum_n = np.cumsum(n)

七、数组的快速排序

  • np.sort():不改变原数组
  • ndarray.sort():改变原数组,不多占用内存
import numpy as np
n1 = np.random.randint(0,10,size=6)
n2 = np.sort(n1) # 默认是升序排序,不改变原数组相当于重新开辟了一块空间
display(n1,n2)
n3 = np.random.randint(0,10,size=6)
n3.sort() # 改变原数组
array([0, 3, 8, 9, 1, 4])

array([0, 1, 3, 4, 8, 9])

八、ndarray文件操作

保存数据

  • save:保存ndarray到一个npy文件
  • savez:将多个array保存到一个npz文件中
import numpy as np
x = np.arange(5)
y = np.arange(10,20)
# save
np.save('x',x)
# savez
np.savez('arr.npz',xarr=x,yarr=y)

读取文件

import numpy as np
# 读取npy文件
np.load('x.npy')
# 读取npz文件
np.load('arr.npz')['yarr']
array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19])

csv、txt文件的读写操作

import numpy as np
n = np.random.randint(0,10,size=(3,4))
# 将数据存储到csv或txt文件中
np.savetxt('arr.csv',n,delimiter=',')
# 从csv文件或txt文件中读取数据
np.loadtxt('arr.csv',delimiter=',',dtype=int)
array([[8, 0, 7, 3],
       [6, 3, 2, 4],
       [9, 3, 8, 7]])

九、例题

知识点差不多讲完了,然后就是需要练习题来检验学习成果,话不多说,我们直接看题:

1、创建一个长度为10的一维全为0的ndarray对象,然后让第五个元素等于1

import numpy as np
a = np.zeros(10,dtype=int)
a[4]=1

2、创建一个元素从10到49的ndarray对象

import numpy as np
b = np.arange(10,50,dtype=int)

3、将第二题的所有元素翻转

import numpy as np
b = np.arange(10,50,dtype=int)
b[::-1]
array([49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33,
       32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
       15, 14, 13, 12, 11, 10])

4、使用np.random.random创建一个10*10的ndarray对象,并打印出最大和最小的元素

import numpy as np
c = np.random.random(size=(10,10))
max_c = np.max(c)
min_c = np.min(c)
display(max_c,min_c)
0.9974378508965802

0.007652520100204452

5、创建一个10*10的ndarray对象,且矩阵边界全为1,里面全为0

import numpy as np
d = np.ones((10,10),dtype=int)
d[1:-1,1:-1]=0
# 实现方法二:
e = np.zeros((10,10),dtype=int)
e[[0,-1]]=1
e[:,[0,-1]]=1

6、创建一个每一行都是0到4的5*5矩阵

import numpy as np
f = np.arange(5)
f = np.tile(f,(5,1))
# 方法二
g = [0,1,2,3,4]
g = np.array(g*5)

7、创建一个范围在0~1之间长度为12的等差数列

import numpy as np
h = np.linspace(0,1,12)

8、创建一个长度为10的随机数组并排序

import numpy as np
i = np.random.randint(0,10,10)
i.sort()

9、创建一个长度为10的随机数组,并将最大值替换为0

import numpy as np
j = np.random.randint(0,10,10)
max_indexs = np.argwhere(j==np.max(j)).reshape(-1)
j[max_indexs]=0

10、给定一个4维矩阵,如何得到最后两维的和

import numpy as np
k = np.random.randint(1,10,size=(2,3,4,5))
k.sum(axis=(2,3))
array([[116, 108, 108],
       [ 94, 103, 101]])

11、给定数组[1,2,3,4,5],如何得到在这个数组的每一个元素之间插入3个0后的新数组

import numpy as np
l = np.arange(1,6)
m = np.zeros(17,dtype=int)
m[::4] = l
m
array([1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5])

12、给定一个二维矩阵,如何交换其中两行元素

import numpy as np
n = np.random.randint(0,10,size=(4,4))
display(n)
temp = n[0].copy()
n[0]=n[1]
n[1]=temp
# 法二
n[[0,1]]=n[[1,0]]
array([[9, 2, 6, 6],
       [6, 1, 3, 2],
       [8, 3, 0, 4],
       [9, 2, 1, 4]])

13、创建一个长度为10000的随机数组,使用两种方法对其求3次方,并比较所用时间

import numpy as np
p = np.random.randint(0,10,size=10000)
# 法一所用时间
%timeit np.power(p,3)
# 法二所用时间
%timeit p**3
38.4 μs ± 9.18 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
40.7 μs ± 5.17 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)

14、创建一个5*3的随机矩阵和一个3*5的随机矩阵,求矩阵积

import numpy as np
n1 = np.random.randint(0,10,size=(5,3))
n2 = np.random.randint(0,10,size=(3,5))
np.dot(n1,n2)
array([[ 83,  62, 114,  82,  53],
       [ 95,  64, 136,  76,  69],
       [ 41,  21,  50,  40,  28],
       [ 79,  76, 115,  87,  44],
       [ 45,  33,  53,  59,  23]])

15、矩阵的每一行的元素都减去该行的平均值

import numpy as np
r = np.random.randint(0,10,size=(3,4))
mean_r = np.mean(r,axis=1).reshape(3,1)
r - mean_r
array([[-2.  ,  5.  , -1.  , -2.  ],
       [-4.5 ,  1.5 , -0.5 ,  3.5 ],
       [-1.25, -3.25, -0.25,  4.75]])

16、正则化一个5*5的随机矩阵

  • 正则的概念:假设a是矩阵中的一个元素,max、min分别是矩阵元素的最大值和最小值,则正则化后a* = (a-min)/(max-min),也可以叫归一化处理
import numpy as np 
n = np.random.randint(0,100,size=(5,5))
display(n)
max_n = np.max(n)
min_n = np.min(n)
display(max_n,min_n)
(n - min_n)/(max_n - min_n)
array([[67, 63, 83, 46, 53],
       [14,  5,  9, 69, 94],
       [76, 74, 53,  2, 31],
       [50, 22, 31, 27,  2],
       [34, 26, 23, 99, 94]])

99

2

array([[0.67010309, 0.62886598, 0.83505155, 0.45360825, 0.5257732 ],
       [0.12371134, 0.03092784, 0.07216495, 0.69072165, 0.94845361],
       [0.7628866 , 0.74226804, 0.5257732 , 0.        , 0.29896907],
       [0.49484536, 0.20618557, 0.29896907, 0.25773196, 0.        ],
       [0.32989691, 0.24742268, 0.21649485, 1.        , 0.94845361]])

猜你喜欢

转载自blog.csdn.net/2401_83283514/article/details/145164140
今日推荐