本文主要是介绍Python與資料分析4-資料視覺化-鳶尾花,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
“Talk is cheap. Show me the code.”
― Linus Torvalds
老子第41章
上德若谷
大白若辱
大方無隅
大器晚成
大音希聲
大象無形
道隱無名
拳打千遍, 身法自然
“There’s no shortage of remarkable ideas, what’s missing is the will to execute them.” – Seth Godin
「很棒的點子永遠不會匱乏,然而缺少的是執行點子的意志力。」—賽斯.高汀
110_1_高中週期性課程: Python程式入門與資料分析初探, 道明高中
本系列文章之連結
- Python程式與數據資料分析1 link
- Python程式與數據資料分析1.1 Kaggle站免費教學的路徑圖 link
- Python 與數據資料分析2-資料視覺化-Matplotlib.pyplot 入門 link
- Python 與數據資料分析3.1-資料視覺化-基本圖表類型 link
- Python 與數據資料分析3.2-資料視覺化-從 seabon 的函數分類來看 link
- Python與資料分析3.3-資料視覺化-seaborn 補充 link
- Python與資料分析4-資料視覺化-鳶尾花 link
- Python與資料分析 5-入門級競賽分析-鐵達尼號 link
文章目录
- 本系列文章之連結
- 資料分析的初學者如何載入鳶尾花 Iris.csv 資料集
- 首先載入各程式庫及鳶尾花 Iris.csv 資料集
- 從 sklearn 載入鳶尾花 Iris 資料集(不推薦)
- 從Kagle或是UCI下載再用`pd.read_csv()`讀入(推薦)
- 用 Pandas, seaborn 做最初步分析
- 用`iris["Species"].value_counts()`統計各品種之數目`
- 用 `iris.plot()` 做最初步的繪圖
- 用 `seaborn.jointplot()` 做最初步的繪圖
- `sns.FacetGrid()`
- 用 `seaborn.jointplot(,hue='Species,)` 也可以呈現不同種類之顏色
- 用 `seaborn.boxplot()` 看Sepal Length 分布
- 用 `seaborn.boxplot()` 看 Petal Length 分布
- `ax = sns.stripplot(, jitter=True,)`
- `violinplot()` 提琴圖, 其實就是把 boxplot() 跟 stripplot() 合起來的圖
- `FacetGrid().map(kdeplot,).add_legend()`
- `pairplot()`(分片) 運用 seaborn 最有名的指令
- 用 Pandas 的指令繪圖
- `data.boxplot(by="Species",)`
- `pandas.plotting.andrews_curves()`
- `pandas.plotting.parallel_coordinates()`
- `pandas.plotting.radviz()` 類似雷達圖
- seaborn 函數分 axes-level(專門型), figure-level(通用型)兩種
- Wrap Up 結尾
- Reference
資料視覺化, 或敘述式統計, 是以直觀的圖表來呈現出資料的分群. 或內含的結構, 關係等.
以下我們講解 Kaggle 站的課程: Python Data Visualizations
Ref: Python Data Visualizations, https://www.kaggle.com/benhamner/python-data-visualizations link
講解用 Python 相關工具對鳶尾花資料做視覺化的分析:
This notebook demos Python data visualizations on the Iris dataset
This Python 3 environment comes with many helpful analytics libraries installed. It is defined by the kaggle/python docker image
使用到3個程式庫: pandas, matplotlib, seaborn
We’ll use three libraries for this tutorial: pandas, matplotlib, and seaborn.
資料分析的初學者如何載入鳶尾花 Iris.csv 資料集
原網頁文章中載入鳶尾花 Iris.csv 資料集, 是已經先在硬碟中有 Iris.csv, 再以 pd.read_csv()
讀入:
iris = pd.read_csv("../input/Iris.csv")
# the iris dataset is now a Pandas DataFrame
但原網頁並沒有說 iris.csv 是怎麼得到的, 對於不時很熟悉 資料分析的初學者, 這也會成為問題的,
資料分析的初學者如何載入資料集:
-
如果是在 R 語言,
可以直接載入> library(ISwR)
, 裡面有很多常用的資料, 或是下> data(package = .packages(all.available = TRUE))
, 查看所有載入的包中有那些現成的 data. -
在 Python, 則可以使用
sklearn
(就是scikit-learn
) 程式庫datasets
, 裡面有很多常用的資料:
from sklearn import datasets
iris = datasets.load_iris()
注意, 從 sklearn 載入的是 字典 dict() 的型態, 主要資料則是 np.array()的型態,
一般如果用 pd.read_csv() 讀入, 則是 DataFrame, 會有較多指令可以使用!
- 另一個方法是到 Kaggle 站內 選 Datasets, 這裡放者許多常用的 data, 搜尋 Iris
- 另一個在資料分析領域常用方法,就是到 UC Irvine(加州大學爾灣分校) 的站下載到硬碟中,
archive.ics.uci.edu/ml
the UC Irvine Machine Learning Repository, 使用搜尋功能.
https://archive.ics.uci.edu/ml/index.php link
首先載入各程式庫及鳶尾花 Iris.csv 資料集
Iirs 的
sepal 是指 萼片
petal 是指 花瓣
Ref: https://en.wikipedia.org/wiki/Sepal link
從 sklearn 載入鳶尾花 Iris 資料集(不推薦)
以下程式碼,
- 載入各個程式庫: pandas, matplotlib, seaborn, sklearn
- 從 sklearn 載入鳶尾花 Iris 資料集(注意, 此時是字典的格式) 而不是 iris.csv)
- 用 print() 印出 Iris
# 20210723 P-J Lai MATH NKNU
##以下我們講解 Kagle 站的課程: **Python Data Visualizations**
##Ref: Python Data Visualizations, https://www.kaggle.com/benhamner/python-data-visualizations [link](https://www.kaggle.com/benhamner/python-data-visualizations)
##講解用 Python 相關工具對鳶尾花資料做視覺化的分析:
##This notebook demos Python data visualizations on the Iris dataset
##This Python 3 environment comes with many helpful analytics libraries installed. It is defined by the kaggle/python docker image
##使用到3個程式庫: **pandas, matplotlib, seaborn**
##We'll use three libraries for this tutorial: pandas, matplotlib, and seaborn.
# PythonDataVisualizations_Iris_Kaggle.pyimport pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="white", color_codes=True)#iris = pd.read_csv("../input/Iris.csv") # the iris dataset is now a Pandas DataFrame# 我們從 sklearn 載入 Iris
import sklearn
from sklearn import datasets
iris = datasets.load_iris()print(iris)
#iris.head()
特別注意
在 sklearn 中对数据有如下要求:
特征’data’和标签’target’要用分开的对象存储
特征和标签要是数字
特征和标签都要使用numpy的array来存储
Ref: 百浪多息, 从iris数据集入门scikit-learn, https://zhuanlan.zhihu.com/p/75127982 link
從 sklearn 載入 Iris 是 字典 dict() 的型態,
‘data’ 屬性放主要資料, 是 np.array()的型態
可以下
print(type(iris['data']))
查詢 iris 的 data 是何資料型態
輸出為
<class 'numpy.ndarray'>
另一屬性 ‘target_names’, 是放置鳶尾花的 3 種名稱:
'target_names': array(['setosa', 'versicolor', 'virginica']
另一屬性 ‘feature_names’ 是指出 data 裏的數字是 4種長度(花萼花瓣等):
‘feature_names’: [‘sepal length (cm)’, ‘sepal width (cm)’, ‘petal length (cm)’, ‘petal width (cm)’]
如果我們想把 從 sklearn 載入 Iris 轉成 pd.DataFrame, 會發現, 出現錯誤訊息: 長度不一致!
iris=pd.DataFrame(iris)
ValueError: arrays must all be same length
從Kagle或是UCI下載再用pd.read_csv()
讀入(推薦)
以下我們將以上的 2. 從 sklearn 載入鳶尾花 Iris 資料集作法改成, 先從 Kagle或是 UCI 下載 iris.csv, 再用 pd.read_csv() 讀入, 則是 DataFrame, 會有較多指令可以使用!
2. 先從 Kagle或是 UCI 下載 Iris.csv (注意, 此時是 Iris.csv), 再用 pd.read_csv() 讀入 為 pd.DataFrame的格式
iris = pd.read_csv("./Iris.csv")
print(iris.head())
# 20210723 P-J Lai MATH NKNU
###############################################################
##以下程式碼,
##1. 載入各個程式庫: **pandas, matplotlib, seaborn, sklearn**
##2. 先從 Kagle或是 UCI 下載 Iris.csv (注意, 此時是 Iris.csv),
##3. 再用 pd.read_csv() 讀入 為 pd.DataFrame的格式,
## 則是 DataFrame, 會有較多指令可以使用!3. 用 print() 印出 Iris.csvimport pandas as pd
##import warnings # current version of seaborn generates a bunch of warnings that we'll ignore
##warnings.filterwarnings("ignore")
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="white", color_codes=True)# 假設已先從 Kagle 或是 UCI 下載 Iris.csv
# 再用 pd.read_csv() 讀入 為 pd.DataFrame的格式iris = pd.read_csv("./Iris.csv")
print(iris.head())
輸出為:
>>>
== RESTART: C:\Users\user\Desktop\PythonDataVisualizations_Iris_pd.read_csv.py =Id SepalLengthCm SepalWidthCm PetalLengthCm PetalWidthCm Species
0 1 5.1 3.5 1.4 0.2 Iris-setosa
1 2 4.9 3.0 1.4 0.2 Iris-setosa
2 3 4.7 3.2 1.3 0.2 Iris-setosa
3 4 4.6 3.1 1.5 0.2 Iris-setosa
4 5 5.0 3.6 1.4 0.2 Iris-setosa
用 Pandas, seaborn 做最初步分析
Pandas, seaborn 的安奘可以參考本系列第一篇: Python 程式與數據資料分析1, https://blog.csdn.net/m0_47985483/article/details/118150492 link
對於從未使用過 Pandas 與 seaborn 的讀者, 可以直接閱讀接下來的各種操作, 我會在適當處加以說明,
但是想要較全面性的了解與掌握, 還是建議閱讀以下的連結資料:
Pandas 入門 的說明, 可以看 Kaggle 上的網頁講義, 或搜雲網路上的網誌也是滿山滿谷, https://www.kaggle.com/learn/pandas link
seaborn 入門 的說明, 可以看 Kaggle 上的網頁講義, 或搜尋網路上的網誌也是滿山滿谷, link
seaborn 的詳細介紹可以參考此篇: herr_kun, python-seaborn画图-(matploytlib)更高级的数据绘图工具, link
用iris["Species"].value_counts()
統計各品種之數目`
iris["Species"].value_counts()
會以 “Species” 這個屬性的值為區別, 去計算在整個 DataFrame資料 中有多少個, 同一種 “Species” 的歸做一類計算數目, Iris 有三種品種, 以下計算出各有 50個.
# 用 Pandas, seaborn 最初步分析print(iris["Species"].value_counts())##輸出
##Iris-virginica 50
##Iris-versicolor 50
##Iris-setosa 50
##Name: Species, dtype: int64
用 iris.plot()
做最初步的繪圖
程式碼:
## 用 `iris.plot()` 做最初步的繪圖iris.plot(kind="scatter", x="SepalLengthCm", y="SepalWidthCm")
plt.show()
iris.plot()
是使用 Pandas 的 plot(), 而非 Matplotlib.pyplot 的 plot(), 但是基本上是用 Matplotlib.pyplot 的 plot() 加以重載而已, 所以大多數使用的參數與方式都類似.
iris.plot(kind="scatter", x="SepalLengthCm", y="SepalWidthCm")
指定
kind=“scatter”: 用散點繪製,
x=“SepalLengthCm”: x 軸是 “SepalLengthCm”, 即 x 軸是萼片的長度,
y=“SepalWidthCm”: y 軸是 “SepalWidthCm”, 即 y 軸是萼片的寬度.
上圖呈現 由萼片的長度, 萼片的寬度, 的不同, 確實讓 樣本呈現出只少兩個群體.
這種就是敘述式統計, 以直觀的圖表來呈現出資料的分群. 或內含的結構關係等.
用 seaborn.jointplot()
做最初步的繪圖
seaborn 會有較豐富的繪圖指令可以運用, 預設的圖形也較美麗, 不需要做太多微細的控制, 可以減輕初學者的負擔, 讓他專心在資料分析的工作上.
sns.jointplot(x="SepalLengthCm", y="SepalWidthCm", data=iris, size=5)
size=5 是指定點的大小
sns.jointplot(x="SepalLengthCm", y="SepalWidthCm", data=iris, size=5)
深入的 jointplot()屬性的使用, 點選 jointplot 位置, 會連結到 jointplot 的詳細說明文件處
https://seaborn.pydata.org/generated/seaborn.jointplot.html#seaborn.jointplot link
sns.FacetGrid()
為了讓每個資料點根據他的種類, 呈現不同顏色, Python Data Visualizations這個教學是使用 sns.FacetGrid()
指令:
sns.FacetGrid(iris, hue="Species", size=5) \.map(plt.scatter, "SepalLengthCm", "SepalWidthCm") \.add_legend()
用 seaborn.jointplot(,hue='Species,)
也可以呈現不同種類之顏色
用這方法比使用sns.FacetGrid()
更清楚直接
加上指定 顏色的屬性
hue='Species'
大家可以看到上圖, jointplot() 自動將預設之 histogram(直方圖頻率圖) 圖改成 kde(核密度) 圖
## 用 `seaborn.jointplot()` 也可以呈現不同種類之顏色
sns.jointplot(x="SepalLengthCm", y="SepalWidthCm", data=iris, size=5, hue='Species')
plt.show()
上圖顯示 橘色的 versicolor, 與 綠色的 verginica 品種是混在一起的, 表示單用萼片的長與寬無法適當的區分這兩種,
以下我們改用 petal 花瓣來區分看看
發現區分的效果很好
## 改用 petal 花瓣來區分看看(發現很區隔開來)
sns.jointplot(x="PetalLengthCm", y="PetalWidthCm", data=iris, size=5, hue='Species')
plt.show()
用 seaborn.boxplot()
看Sepal Length 分布
sns.boxplot(x="Species", y="SepalLengthCm", data=iris)
plt.show()
用 seaborn.boxplot()
看 Petal Length 分布
可以看出三個種類的分布集中程度, 用 Petal(花瓣) 看, 分布的狀況有較拉開
sns.boxplot(x="Species", y="PetalLengthCm", data=iris)
plt.show()
ax = sns.stripplot(, jitter=True,)
網頁上說明:
Saving the resulting axes as ax each time causes the resulting plot to be shown on top of the previous axes
意思就是, 可以將圖存為 ax, 如此, 後面的圖會疊在已先產生的圖上.
stripplot(, jitter=True,)
的 jitter, 會讓 點, 稍微左右挪動, 不會落在通一條垂直線上, 可以讓點的分布更清楚呈現,
# Saving the resulting axes as ax each time causes the resulting plot
# to be shown on top of the previous axes
ax = sns.boxplot(x="Species", y="PetalLengthCm", data=iris)
ax = sns.stripplot(x="Species", y="PetalLengthCm", data=iris, jitter=True, edgecolor="gray")
sns.stripplot()
就是散點圖
seaborn.stripplot(*, x=None, y=None, hue=None, data=None, order=None, hue_order=None, jitter=True, dodge=False, orient=None, color=None, palette=None, size=5, edgecolor='gray', linewidth=0, ax=None, **kwargs)
Draw a scatterplot where one variable is categorical.
就是散點圖, 適合跟 boxplot(), violinplot() 等結合使用
上圖就是跟 boxplot()結合使用之例子!
Ref: sns.stripplot()
link
violinplot()
提琴圖, 其實就是把 boxplot() 跟 stripplot() 合起來的圖
上面跟 stripplot() 跟 boxplot()結合使用之例子, 可以用 violinplot()一個指令來實現.
# A violin plot combines the benefits of the previous two plots
# and simplifies them
# Denser regions of the data are fatter, and sparser thiner in
# a violin plot
# 提琴圖, 其實就是把 boxplot() 跟 stripplot() 合起來的圖:
sns.violinplot(x="Species", y="PetalLengthCm", data=iris, size=6)
plt.show()
Ref: sns.violinplot()
link
FacetGrid().map(kdeplot,).add_legend()
kdeplot() 可以產生指定屬性的和密度估計圖
A final seaborn plot useful for looking at univariate relations is the kdeplot,
which creates and visualizes a kernel density estimate of the underlying feature
# A final seaborn plot useful for looking at univariate relations is the kdeplot,
# which creates and visualizes a kernel density estimate of the underlying feature
sns.FacetGrid(iris, hue="Species", size=6) \.map(sns.kdeplot, "PetalLengthCm") \.add_legend()plt.show()
pairplot()
(分片) 運用 seaborn 最有名的指令
pairplot( data)
可以畫出 data 各屬性兩兩交互的分布(分片)圖, 例如 花萼寬度對花萼長度, 或 花萼寬度
對花瓣長度, 等等.
iris.drop("Id", axis=1)
此指令則是先去掉 下標編號 0,1,2,3,這一直行,
axis=1
, 指定沿著 column(直行) 刪除
axis=0
, 則是指定沿著 row(橫行) 刪除
# Another useful seaborn plot is the pairplot, which shows the bivariate relation
# between each pair of features
#
# From the pairplot, we'll see that the Iris-setosa species is separataed from the other
# two across all feature combinations
sns.pairplot(iris.drop("Id", axis=1), hue="Species", size=3)
plt.show()
預設的效果, 與以下指定 diag_kind="kde"
, 是一樣的
指定其他的, 例如 ecdf, box, swarm 等都有 error
sns.pairplot(iris.drop("Id", axis=1), hue="Species", size=3, diag_kind="kde")
plt.show()
透過 pairplot()
分片繪圖, 我們可以立即看出 藍色 setosa 這個種類在各個屬性都與其他兩個種類區隔得很清楚,
另一方面, 花瓣寬PetalWidthCm 或花瓣長PetalLengthCm 都與其他屬性呈現清楚的區隔(分類)效果,
也可看出, PetalLengthCm 對 SepalLengthCm 的分類效果最好.
用 Pandas 的指令繪圖
data.boxplot(by="Species",)
Pandas 的 DataFrame 可以用 by="Species"
來分群繪圖
iris.drop(“Id”, axis=1).boxplot(by="Species"
, figsize=(12, 6))
# Now that we've covered seaborn, let's go back to some of the ones we can make with Pandas
# We can quickly make a boxplot with Pandas on each feature split out by species
# by="Species", 用種類分群
iris.drop("Id", axis=1).boxplot(by="Species", figsize=(12, 6))
plt.show()
pandas.plotting.andrews_curves()
原網頁的指令是較早期的
from pandas.tools.plotting
import andrews_curves
andrews_curves(iris.drop(“Id”, axis=1), “Species”)
現在只要直接下
pandas.plotting.andrews_curves()
pd.plotting.andrews_curves(iris.drop("Id", axis=1), "Species")
plt.show()
# One cool more sophisticated technique pandas
# has available is called Andrews Curves
# Andrews Curves involve using attributes of
# samples as coefficients for Fourier series
# and then plotting these
# 這是早期的作法: from pandas.tools.plotting
# import andrews_curves
pd.plotting.andrews_curves(iris.drop("Id", axis=1), "Species")
plt.show()
pandas.plotting.parallel_coordinates()
另一個類似的呈現方式, 是 parallel_coordinates()
:
Another multivariate visualization technique pandas has is parallel_coordinates
Parallel coordinates plots each feature on a separate column & then draws lines
connecting the features for each data sample
pd.plotting.parallel_coordinates(iris.drop("Id", axis=1), "Species")
pd.plotting.parallel_coordinates(iris.drop("Id", axis=1), "Species")
plt.show()
pandas.plotting.radviz()
類似雷達圖
pandas.plotting.radviz() 類似雷達圖, 將四個屬性均分在一個圓周上, 再按比例描點, 就可以看出該資料點在四個屬性裡的比值.
但是雷達圖 每個資料點會有4個屬性, 就會標出4個點, 做出一個多邊形, 讓讀者感覺該資料點在哪個屬性較強,
而 radviz()
在四個屬性裡只標出一個點, 按他在在四個屬性裡的比值, 決定他離哪個屬性較近, 值較大的那個屬性, 就表示該彈簧之彈性係數大, 則不易拉開, 則此點就較接近值較大的那個屬性, (當然各屬性值必須先歸一化 normalized)
所以直觀上理解 radviz(): 點較接近屬性值較大的那個屬性的位置.
Ref: 一叶_障目, Radviz可视化原理, https://blog.csdn.net/Haiyang_Duan/article/details/78985225, link
A final multivariate visualization technique pandas has is radviz Which puts each feature as a point on a 2D plane, and then simulates having each sample attached to those points through a spring weighted by the relative value for that feature
這是早期的作法: from pandas.tools.plotting import radviz
pd.plotting.radviz(iris.drop("Id", axis=1), "Species")
plt.show()
# 這是早期的作法: from pandas.tools.plotting
# import radviz
pd.plotting.radviz(iris.drop("Id", axis=1), "Species")
plt.show()
seaborn 函數分 axes-level(專門型), figure-level(通用型)兩種
在學seaborn 時, 在網路上的說明, 常常 同樣的效果,各家的指令都不同, 會讓初學者感到混亂, 其實可以先了解 seaborn 的設計, 繪圖函數 基本上分通用型 figure-level 與專門型 axes-level兩種類別.
參考下圖, 最上方的函數, 屬於 figure-level 的函數, 之後的較小字體的則是 axes-levle functions,
- figure-level 函數function: 可視為通用型的, 例如 distplot(), 加上例如 kind=“kde”, 就會呈現跟 kdeplot()一樣的效果, 透過更換 kind=" " 的指定, 可以更換它下方的任一個繪圖, 例如 distplot() 涵蓋 histplot(), kdeplot(), ecdfplot(), rugplot().
- axes-levle funciton: 可視為專門型的, 指執行特定的繪圖, 下圖較小字體的都是 axes-levle functions,
seaborn 有所有函數與指令的列表, 可以參考官網 API reference:
https://seaborn.pydata.org/api.html link
Wrap Up 結尾
希望你享受這個快速地介紹, 透過Python 中的 pandas, seaborn, and matplotlib 我們可以快速的產生資料的視覺畫分析.
I hope you enjoyed this quick introduction to some of the quick, simple data visualizations you can create with pandas, seaborn, and matplotlib in Python!
我鼓勵你自己重複這些指令操作, 以此為基礎, 將這些方法用在其他的資料集上, 或整合進你的工作流程
I encourage you to run through these examples yourself, tweaking them and seeing what happens. From there, you can try applying these methods to a new dataset and incorprating them into your own workflow!
到 Kaggle 的 Datasets 區域找其他的資料集練習, The World Food Facts 這個資料集非常適合視覺化的練習!
See Kaggle Datasets for other datasets to try visualizing. The World Food Facts data is an especially rich one for visualization.
Reference
-
Python Data Visualizations, https://www.kaggle.com/benhamner/python-data-visualizations link
-
百浪多息, 从iris数据集入门scikit-learn, https://zhuanlan.zhihu.com/p/75127982 link
-
Kaggle 的網頁上的教學: Pandas教學, https://www.kaggle.com/learn/pandas link
seaborn
-
seaborn 的詳細介紹可以參考此篇: herr_kun, python-seaborn画图-(matploytlib)更高级的数据绘图工具, https://blog.csdn.net/herr_kun/article/details/87697639?utm_term=python%E7%94%BB%E5%9B%BE%E5%BA%93seaborn&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-6-87697639&spm=3001.4430 link
-
Kaggle 此處的教學就是使用 seaborn: Data Visualization 資料視覺化教學, https://www.kaggle.com/learn/data-visualization link
-
seaborn 的教學: https://seaborn.pydata.org/tutorial.html link
-
seaborn 有所有函數與指令的列表, 可以參考官網 API reference
https://seaborn.pydata.org/api.html link -
深入的 jointplot()屬性的使用, 點選 API reference
jointplot
位置, 會連結到 jointplot 的詳細說明文件處
https://seaborn.pydata.org/generated/seaborn.jointplot.html#seaborn.jointplot link -
stripplot()
, https://seaborn.pydata.org/generated/seaborn.stripplot.html#seaborn.stripplot link -
sns.violinplot()
https://seaborn.pydata.org/generated/seaborn.violinplot.html#seaborn.violinplot link -
一叶_障目, Radviz可视化原理, https://blog.csdn.net/Haiyang_Duan/article/details/78985225, link
这篇关于Python與資料分析4-資料視覺化-鳶尾花的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!