2.机器学习小记录–机器学习常用的python包

目录:

一、numpy

二、pandas

三、matplot

四、seaborn

一、Numpy

1、numpy的介绍

numpy是python语言的一个第三方库,其支持大量高维度数组和矩阵运算(二位数组) ,此外numpy也针对数组运算提供了大量的数学函数。机器学习涉及到大量对数组的变换和运算,numpy就成了必不可少的工具之一。

numpy是使用python进行科学计算的基础库,主要提供高性能的N维数组计算能力。

2、导入numpy库,并命名为np

import numpy as np

3、如何创建

通过列表创建一维数组:

np.array([1,2,3])

通过列表创建一个二维数组:

np.array([(1,2,3),(4,5,6)])

创建全为0的二维数组:

np.zeros((3,4))

创建全为1的三位数组:

np.ones((2,3,4))

4、数组运算

a = np.array([10, 20, 30, 40, 50])

b = np.arange(1, 6)

a, b

求和

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

np.sum(a)

12.一维数组加法运算:a + b

13 一维数组减法运算:a – b

  1. 一维数组乘法运算:a * b

15.一维数组除法运算:a / b

二、Pandas

2.1 pandas

pandas纳入了大量库和一些标准的数据类型,提供了高效地操作大型数据集所需的工具。 pandas提供了大量能使我们快捷处理数据的函数和方法。

与numpy对比:numpy能够帮助我们处理数值,pamdas除了处理数值之外,还能帮助我们处理其它类型数据。

pandas主要用于数据分析和数据可视化

2.2pandas常用的数据类型

series: Series类似一维数组,由索引和一组数据组成,其中索引在左边,值在右边。

1、pandas系列可以使用以下构造函数创建

import pandas as pd

import numpy as np

data=np.array([“a”,”b”,”c”,”d”])

s=pd.series(data) #index 默认np.arrange(n)如果没有索引被传递

print(s)

s=pd.series(data,index=[100,1011,102,103])

print(s)

输出结果:

0 a

1 b

2 c

3 d

type: object

100 a

101 b

102 c

103 d

dtype: object

2.从字典(dict)数据创建pandas系列,字典作为输入传递, 如果没有指定索引,则按照排列顺序取得字典键构造索引,如果传递了索引,索引中与标签对应的数据中的值将被拉出

import pandas as pd

import numpy as np

data={“a”:0.,”b”:1.,”c”:2.}

s=pd.series(data) # 没有指定索引,则按照排列顺序取得字典键构造索引

print(s)

s=pd.series(data,[“b”,”c”,”d”,”a”]) # 传递了索引,索引中与标签对应的数据中的值将被拉出

print(s)

输出结果:

a 0.0

b 1.0

c 2.0

dtype: float64

b 1.0

c 2.0

d NaN

a 0.0

dtype: float64

3.从标量数据创建Pandas系列,数据是标量值,则必须提供索引。将重复
该值以匹配索引的长度

import pandas as pd

import numpy as np

s = pd.Series(5, index=[0, 1, 3])

print(s)

输出结果:

0 5

1 5

3 5

dtype: int64

DataFrame:数组帧(DataFrame)是二维数据结构,即数据以行和列的表格方式排列

pandas中的DataFrame可以使用以下构造函数构建: pandas.DataFrame(data,index,columns,dtype)

• data数据采取各种形式,如:ndarray,series,map,lists,dict,constant和另一个DataFrame。
• index对于行标签,要用于结果帧的索引是可选缺省值np.arrange(n),如果没有传递索引值。
• columns对于列标签,可选的默认语法是 – np.arange(n)。 这只有在没有索引传递的情况下才是这样。
• dtype每列的数据类型。

import pandas as pd
import numpy as np
df = pd.DataFrame()#empty DataFrame
print(df)
data = [1, 2, 3, 4, 5]
df = pd.DataFrame(data) #from list
print(df)
data = [[‘Alex’, 10], [‘Bob’, 12], [‘Clarke’, 13]]
df = pd.DataFrame(data, columns=[‘Name’, ‘Age’]) # from list
print(df)

输出结果:

Empty DataFrame Columns: []

Index: []

0

0 1

1 2

2 3

3 4

4 5

Name Age

0 Alex 10

1 Bob 12

2 Clarke 13

三、matplotlib

matplotlib基本介绍

matplotlib是一个在python下实现的类matplot的纯python的第三方库,旨在python实现matlab的功能,是python下最出色的绘图库。

matplotlib中应用最广的是matlpotlib.pyplot模块

matplotlib绘图基础

2.机器学习小记录--机器学习常用的python包

.figure() :创建一个新的绘图窗口。

.figtext() :为figure添加文字

.axes() :为当前figure添加一个坐标轴

.plot() :绘图函数

.axis() :坐标的取值范围

.test() :在轴上添加文字

.xlabel/ylabel() :设置当前图框状态;off或者on

.imread() :读取一个图像,从图像文件中提取数组

.legend() :为当前axes放置标签

.scatter() :做一个x和y的散点图,其中x和y是相同长度的序列对象

1.创建画布与创建子图

plt.figure()创建一个空白画布,指定画布大小,像素。

figure.add_subplot() :创建并选中子图,可以指定子图的行数,列数,与选中图片编号

plt.figure()主要作用是构建出一张空白的画布,figure.add_subplot() 选择将整个画布划分为多个部分,方便在同一画布上绘制多个图形的情况。最简单的绘图plt.figure(),而后直接在默认的画布上进行图形绘制。

import matplotlib.pyplot as plt

import numpy as np

data=np.arrange(10)

plt.plot(data) #plt.plot()绘图函数

输出结果:

2.机器学习小记录--机器学习常用的python包

绘制的图位于图片(figure)对象中。

创建子图

import matplotlib.pyplot as plt

fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图

ax1=fig.add_subplot(2,2,1)

ax2=fig.add_subplot(2,2,2)

ax3=fig.add_subplot(2,2,3)

输出结果:

2.机器学习小记录--机器学习常用的python包

import matplotlib.pyplot as plt

fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图

fig=plt.figure() #本次绘图有多个子图,不能使用空白的figure绘图,需要创建子图

ax1=fig.add_subplot(2,2,1)

ax2=fig.add_subplot(2,2,2)

ax3=fig.add_subplot(2,2,3)

ax1.plot([1.5,2,3.5,-1,1.6])

输出结果:

2.机器学习小记录--机器学习常用的python包

2.添加画布内容

函数名称 函数作用
plt.title 在当前图形中添加标题,可以指定标题的名称、位置、颜色、字体大小等参数。
plt.xlabel 在当前图形中添加x轴名称,可以指定位置、颜色、字体大小等参数。
plt.ylabel 在当前图形中添加y轴名称,可以指定位置、颜色、字体大小等参数。
plt.xlim 定当前图形x轴的范围,只能确定一个数值区间,而无法使用字符串标识。
plt.ylim 指定当前图形y轴的范围,只能确定一个数值区间,而无法使用字符串标识。
plt.xticks 指定x轴刻度的数目与取值。
plt.yticks 指定y轴刻度的数目与取值。
plt.legend 指定当前图形的图例,可以指定图例的大小、位置、标签。

这一部分是绘图的主体部分。其中添加标题,坐标轴名称,绘制图形等步骤是并列的,没有先后顺序,可以先绘制图形,也可以先添加各类标签。但是添加图例一定要在绘制图形之后。

import numpy as np

import matplotlib.pyplot as plt

data=np.arrange(0,1,0.01)

plt.title(“my lines example”)

plt.xlabel(“x”)

plt.ylabel(“y”)

plt.xlim(0,1)

plt.ylim(0,1)

plt.xticks([0,0.2,0.4,0.6,0.8,1])

plt.yticks([0,0.2,0.4,0.6,0.8,1])

plt.plot(data,data**2)

plt.plot(data,data**3)

plt.legend([‘y=x^2′,’y=x^3’])

plt.show()

输出结果:

2.机器学习小记录--机器学习常用的python包

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
data=np.arange(0,np.pi*2,0.01)
fig1=plt.figure(figsize=(9,7),dpi=90)

确定画布大小

绘制第一幅子图

ax1=fig1.add_subplot(1,2,1)
plt.title(‘lines example’)
plt.xlabel(‘X’)
plt.ylabel(‘Y’)
plt.xlim(0,1)
plt.ylim(0,1)
plt.xticks([0,0.2,0.4,0.6,0.8,1])
plt.yticks([0,0.2,0.4,0.6,0.8,1])
plt.plot(data,data2)
plt.plot(data,data
3)

绘制第二幅子图

ax1=fig1.add_subplot(1,2,2)
plt.title(‘sin-cos’)
plt.xlabel(‘X’)
plt.ylabel(‘Y’)
plt.xlim(0,np.pi2)
plt.ylim(-1,1)
plt.xticks([0,np.pi/2,np.pi,np.pi
3/2,np.pi*2])
plt.yticks([-1,-0.5,0,0.5,1])
plt.plot(data,np.sin(data))
plt.plot(data,np.cos(data))
plt.legend([‘sin’,’cos’])
plt.show()

输出结果:

2.机器学习小记录--机器学习常用的python包

Matplotlib 的 Legend 图例就是为了帮助我们展示每个数据对应的图像名称,更好的让读者认识到你的数据结构。关于plt.legend()的说明如下:

2.机器学习小记录--机器学习常用的python包

常用设置示例:

plt.legend(loc = ‘best’,frameon = False)

去掉图例边框,推荐使用

plt.legend(loc = ‘best’,edgecolor = ‘blue’)

设置图例边框颜色

plt.legend(loc = ‘best’,facecolor = ‘blue’)

设置图例背景颜色,若无边框,参数无效

3.绘图的保存与显示

函数名称函数作用plt.savafig保存绘制的图片,可以指定图片的分辨率、边缘的颜色等参数。plt.show在本机显示图形

第三部分主要用于保存和显示图形。

fig.savefig(save_path, format=’png’, transparent=True, dpi=300, pad_inches = 0)

figure.savefig选项

2.机器学习小记录--机器学习常用的python包

四、seaborn

>seaborn简介

seaborn是基于matplotlib的数据可视化库。它在matplotlib的基础上,进行了更高级的封装,从而使得绘图更加容易,不需要经过大量的调整,就能使图像变得精致。

seaborn的几个鲜明特点如下:

绘图接口更加集成,可以通过少量的参数设置实现大量封装绘图。

多数图表具有统计学含义,例如分布、关系、统计、回归等

对pandas和numpy数据类型支持非常友好

>导入seaborn

seaborn的依赖库为numpy、pandas、matplotlib、scipy。

import numpy as np

import pandas as pd

import seaborn as sns

import matplotlib.puplot as plt

from scipy import stats,integrate

1、深度了解Seaborn

1.1 鸢尾花识别

假设我们要创建一个智能手机应用程序,从智能手机拍摄的照片中自动识别花的种类。 我们正在与一个数据科学家团队合作,该数据科学主管负责创建一个演示机器学习模型,测量花的萼片长度 (sepal length),萼片宽度 (sepal width),花瓣长度 (petal length) 和花瓣宽度 (petal width) 四个变量,并根据这些测量识别物种。

那么什么是萼片呢?萼片是花的最外一环。下图清晰指出花的萼片和花瓣。

2.机器学习小记录--机器学习常用的python包

我们的数据集里面包括三种类型的鸢尾花的测量,如下图

2.机器学习小记录--机器学习常用的python包

根据每种鸢尾花的四个数据 (萼片长/宽和花瓣长/宽),我们最终目的是想正确的分类这三种花。但 重中之重的第一步是数据处理,有了干净数据之后再来机器学习很容易

但怎么处理数据有时候更像一门艺术而不像一门科学。接下来会从

1.检查数据
2.清理数据
3.测试数据

三方面来探索,在其过程中当然会借助 Seaborn.

即便是政府或银行,他们公布的数据也有错误。在花费太多时间分析数据之前,提早检查并修正这些错误能节省大量时间。一般来说,我们希望回答以下问题:

1.据格式有什么问题吗?
2.数据数值有什么问题吗?
3.数据需要修复或删除吗?

检查点1.数据格式
首先用 pandas 读取 csv 文件并将数据存成 DataFrame 格式。

iris_data = pd.read_csv( 'iris-data.csv',  na_values=['NA'] )

函数 read_csv() 里面用到的两个参数

  • 第一个 filename 是读取 csv 文件名
  • 第二个参数用来把 csv 里面空白处用 NaN 代替

此行代码将 csv 里的数据转成 pandas 里的数据表,命名为 iris_data。接着查看其前 10 个数据。

iris_data.head(10)

2.机器学习小记录--机器学习常用的python包

数据看起来是可用的 (大神 Hadley Wickhan 对干净数据的定义是,每一列代表一个特征;每一行代表一个样例)。

数据的第一行定义了列标题,标题的描述足以让我们了解每个列代表的内容 (萼片长度,萼片宽度,花瓣长度和花瓣宽度),标题甚至给我们记录测量的单位 (cm, 厘米)

第一行之后的每一行代表一个花的观测数据:四个测量指标和一个类 (class),它告诉我们花的种类。比如前 10 个都是山鸢尾花 (注意第 8 到 10 个的花瓣宽度没有数据,用 NaN 来表示)。

检查点2.数据统计

接下来,检查数据的分布可以识别异常值。我们从数据集的汇总统计数据开始。

iris_data.describe()

2.机器学习小记录--机器学习常用的python包

解释一下上表:

describe() 函数的产出每列数据的个数 (count),均值 (mean),标准差 (std),最小值 (min) 25, 50 和 75 百分位数 (25%, 50%, 75%) 和最大值 (max)。50 百分位数也就是中位数 (median)。

从该表中看到几个有用的值。 例如,我们看到缺少 5 条花瓣宽度的数据 (表里 count 那一行的萼片长度,萼片宽度和花瓣长度的个数都是 150 个,唯独花瓣宽度是 145 个)。

此外,这样的表给不了太多有用信息,除非我们知道数据应该在一个特定的范围 (如萼片长度的最小值是 0.055, 和它其他指标如均值和几个百分位数都不是量纲的,很有可能是测量错误)。

你说表中这些数字看起来是不是很枯燥,为什么不用直观的图呢?现在 seaborn 可以派上用场了。

sb.pairplot(iris_data.dropna(), hue='class')

2.机器学习小记录--机器学习常用的python包

上面 pairplot() 函数里

第一个参数 iris_data.dropna() 就是除去 NaN 的数据表,这么做原因很简单,图里不可能显示的出 NaN 值的。

第二个参数 hue = ‘class’ 就是根据类 (class) 下不同的值赋予不同的颜色 (hue 是色彩的意思)

让我们再回顾一下 iris_data 的前 10 行:

2.机器学习小记录--机器学习常用的python包

它有 5 列,前四列 (萼片长度,萼片宽度,花瓣长度和花瓣宽度) 可看成自变量,第五列 (类) 可看成变量。

配对图 (pairplot) 绘制前四列变量的关系图,而且用不同颜色区分不同的类下面的这四个变量。 从上图可知,横轴纵轴都有四个变量,那么总共可以画出 16 (4*4) 张小图。

对角线上的 4 张都是某个变量和自身的关系,用分布图 (dist plot)。

非对角线的 12 张就是某个变量和另一个变量的关系,用散点图 (scatter plot)。比如第一行第二列的图描述的就是萼片长度 (看纵轴第一个 sepal_length_cm 字样) 和萼片宽度 (看横轴第二个 sepal_width_cm 字样)。

让再回顾「配对图」

2.机器学习小记录--机器学习常用的python包

从「配对图」中,我们可以迅速看出数据集上的一些问题:

1.图的右侧标注这五个类 (Iris-setosa, Iris-setossa, Iris-versicolor, versicolor, Iris-virginica),但原本要分类的花只有三类 (Iris-setosa, Iris-versicolor, Iris-virginica)。这意味着在记录数据时可能会犯下一些错误。

2.在测量中有一些明显的异常值可能是错误的。

第二行的图 1-2-4 (或第二列的图1-2-4),对于 Iris-setosa,一个萼片宽度 (sepal_width) 值落在其正常范围之外。

第一行后三张图 (或第一列后三张图),对于 Iris-versicolor,几个萼片长度 (sepal_length) 值都接近零。

下一步我们的任务是要处理错误的数据。

修正点1.数据类型

问题:按理说鸢尾花应该只有三类,而图中显示有五类。

通过观察数据的标签,我们发现

  • 忘记在 Iris-versicolor 之前添加 Iris-
  • 在 Iris-setossa 中多打了一个 s

现在让我们使来修正这些错误。

>iris_data.loc[iris_data[‘class’]==’versicolor’,’class’]=’Iris-versicolor’
>iris_data.loc[iris_data[‘class’]==’Iris-setossa’,’class’]=’Iris-setosa’

>iris_data[‘class’].unique()

第一行将 versicolor 改为 Iris-versicolor;第二行将 Iris-setossa 改为 Iris-setosa;第四行用 unique() 函数 (unique 有唯一不重复的意思) 检验修改过的数据只有三类,更新后再画「配对图」。

sns.pairplot(iris_data.dropna(), hue='class')

2.机器学习小记录--机器学习常用的python包

完美!五个类减到三个类,而且名称正确,分别是 Iris-setosa, Iris-versicolor 和 Iris-virginica。

修正点2.异常值

修正异常值 (outliers) 是一件棘手的事情。因为我们很难判断异常值是否由测量误差引起,或者是不正确的单位记录数据,或者是真正的异常。如果我们决定排除任何数据,需要记录排除的数据并提供排除该数据的充分理由。由上节所知,我们有两种类型的异常值。

问题1:山鸢尾花的一个萼片宽度值落在其正常范围之外。

2.机器学习小记录--机器学习常用的python包

通过调查我们知道,山鸢尾花 (Iris-setosa) 的萼片宽度 (sepal_width_cm) 不可能低于 2.5 厘米。显然,这个记录是错误的,这种情况下最有效的方法是删除它而不是花时间查找原因。但是,我们仍需要知道有多少个类似这样的错误数据,如果很少删除它没有问题,如果很多我们需要查明原因

cond = (iris_data['class'] == 'Iris-setosa')
     & (iris_data['sepal_width_cm'] < 2.5)
iris_data.loc[cond]

2.机器学习小记录--机器学习常用的python包

上面代码是用数据表里的 loc[] 切片来找到类为 Iris-setoa 并且 sepal width 小于 2.5 的所有行。最后发现只有一个这样的数据,因此可以直接删除此数据。

去掉 Iris-setosa 里萼片宽度大于 2.5 厘米的数据,然后画出其条形图。

iris_data = iris_data.loc[~cond]
iris_data.loc[iris_data['class'] == 'Iris-setosa',
             'sepal_width_cm'].hist()

2.机器学习小记录--机器学习常用的python包

从上面条形图也看到了再没有这个异常值 (小于 2.5 厘米的点)。

完美! 现在所有的山鸢尾花的萼片宽度都大于 2.5 厘米

问题2:变色鸢尾花的几个萼片长度值接近于零。

2.机器学习小记录--机器学习常用的python包

所有这些接近零的 sepal_length_cm 似乎错位了两个数量级,好像它们的记录单位米而不是厘米。在经过了解,我们发现错误是因为忘记将这些测量值转换为厘米。

我们使用代码来修正这些错误。

cond = (iris_data['class'] == 'Iris-versicolor')
     & (iris_data['sepal_length_cm'] < 1.0)
iris_data.loc[cond]

2.机器学习小记录--机器学习常用的python包

>iris_data.loc[cond, ‘sepal_length_cm’] *= 100.0

>iris_data.loc[iris_data[‘class’] == ‘Iris-versicolor’,’sepal_length_cm’].hist()

2.机器学习小记录--机器学习常用的python包

从上面条形图也看到了再没有这五个异常值 (零点零几的点)。

完美! 我们成功修正了这些异常值,要不然以后会 GIGO (Garbage In Garbage Out)

修正点3.缺失值

对了,我们还有些 NaN 这样的缺失值 (missing value)。通常我们有两种方式来处理这类数据。

  • 删除 (deletion)
  • 插补 (imputation)

在本例中删除不是理想的做法,特别是考虑到它们都在 Iris-setosa 下,如图:

2.机器学习小记录--机器学习常用的python包

所有缺失的值都属于 Iris-setosa类,直接删除可能会对日后数据分析带来偏差。此外,可以用插补方法,其最常见的方法平均插补 (mean imputation)。其做法就是”假设知道测量的值落在一定范围内,就可以用该测量的平均值填充空值”。

首先查看缺失值在 DataFrame 哪个位置
iris_data.loc[(iris_data[‘sepal_length_cm’].isnull())|
(iris_data[‘sepal_width_cm’].isnull())|
(iris_data[‘petal_length_cm’].isnull())|
(iris_data[‘petal_width_cm’].isnull())]

2.机器学习小记录--机器学习常用的python包

上面代码里面 iris_data[A].isnull() 语句是找出 A 列中值为 NA 或 NaN 的行,而 “|” 是”或”的意思。因此上面整句话是找到萼片长度,萼片宽度,花瓣长度和花瓣宽度这四列下的所有含 NaN 的行数据,最后发现只有 5 行,而且 NaN 都来自花瓣宽度。

然后用 mean() 求出其宽度的平均值,用其将 NaN 值全部代替,最后打印出那 5 行插补后的 DataFrame。
>isSetosa=iris_data[‘class’]==’Iris-setosa’
>average_petal_width=iris_data.loc[isSetosa,’petal_width_cm’].mean()
>iris_data.loc[isSetosa & >(iris_data[‘petal_width_cm’].isnull()),’petal_width_cm’]=average_petal_width
>iris_data.loc[isSetosa & (iris_data[‘petal_width_cm’]==average_petal_width)]

2.机器学习小记录--机器学习常用的python包

为了确保所有 NaN 值已被替换,再次用 iris_data[A].isnull() 语句来查看,出来的结果是一个只有列标题的空数据表。这表示表内已经没有 NaN 值了。

> iris_data.loc[(iris_data[‘sepal_length_cm’].isnull())|
(iris_data[‘sepal_width_cm’].isnull())|
(iris_data[‘petal_length_cm’].isnull())|
(iris_data[‘petal_width_cm’].isnull())]

2.机器学习小记录--机器学习常用的python包

经过了修正类别、异常值和缺失值后,最后来看看基于干净数据画的「配对图」吧。

sns.pairplot( iris_data,  hue='class' )

2.机器学习小记录--机器学习常用的python包

从上图可看到:

  • 五个类变成三个类
  • 异常值全部被删除
  • 缺失值全部被插补

图整洁了,数据也干净了,之后可以用来做机器学习。

3.加载样本 数据

seaborn附带了样本数据集,所有数据集均为csv格式,数据集默认存放在线上,地址为 https://github.com/mwaskom/seaborn-data

3.1获取样本数据地址 seaborn.get_data_home()

函数签名为 seaborn.get_data_home(data_home=None)

返回值为样本数据集的缓存地址。这个用于 seaborn.load_dataset()

3.2加载数据集 seaborn.load_dataset()

3.2.1 默认从网络加载数据集。

函数的签名为seaborn.load_dataset(name,cache=True,data_home=None,**kws)。

函数的参数为:

&#xA0; <span>name</span>:数据集的名称,对应 https://github.com/mwaskom/seaborn-dataname.csv。字符串。

cache:是否从网络下载数据集。布尔值。可选参数。当取值为 True时,首选从本地缓存加载数据,如果下载数据会将数据缓存在本地。

data_home:缓存目录。字符串,可选参数。默认值为 None,即 get_data_home()

kws:传递给 pandas.read_csv()的附加参数。键值对,可选参数。

返回值为 pandas.DataFrame

3.2.2加载本地数据集

由于数据集默认从github下载,由于网络不稳定或者没有网络,所以直接访问数据集可能不方便,因此加载本地数据集比较灵活。

加载本地数据集的步骤如下:

1、直接从https://github.com/mwaskom/seaborn-data 下载数据集。
2、将数据集保存在同一个目录中,比如D:\seaborn-data。
3、加载数据时,设置load_dataset函数的cache参数为True,data_home参数为D:\seaborn-data。即sns.load_dataset(‘iris’,data_home=r’D:\seaborn-data’,cache=True)

3.2.3加载自定义数据集

除了 seaborn附带的数据集,也可以自己创建数据。

根据 load_data()函数概述可知,其原理就是利用 pandas.read_csv()函数读取 csv文件,因此,只要数据最终被转换为 DataFrame格式即可。

Original: https://blog.csdn.net/weixin_41395763/article/details/122901935
Author: 温旧酒一壶~
Title: 2.机器学习小记录–机器学习常用的python包

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/762728/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球