确定最佳聚类数matlab代码_详解DBSCAN聚类

使用DBSCAN标识为员工分组

cf27109dbb09b15c0f54817c3da4a0c2.png

照片由Ishan @seefromthesky 在 Unsplash拍摄

基于密度的噪声应用空间聚类(DBSCAN)是一种无监督的ML聚类算法。无监督的意思是它不使用预先标记的目标来聚类数据点。聚类是指试图将相似的数据点分组到人工确定的组或簇中。它可以替代KMeans和层次聚类等流行的聚类算法。

在我们的示例中,我们将检查一个包含15,000名员工的人力资源数据集。数据集包含员工的工作特征,如工作满意度、绩效评分、工作量、任职年限、事故、升职次数。

KMeans vs DBSCAN

KMeans尤其容易受到异常值的影响。当算法遍历质心时,在达到稳定性和收敛性之前,离群值对质心的移动方式有显著的影响。此外,KMeans在集群大小和密度不同的情况下还存在数据精确聚类的问题。K-Means只能应用球形簇,如果数据不是球形的,它的准确性就会受到影响。最后,KMeans要求我们首先选择希望找到的集群的数量。下面是KMeans和DBSCAN如何聚类同一个数据集的示例。

7d26f0f891da816b96d50a21436360cb.png
7609b19dfa36cf4a70b139b588ffbdc2.png

另一方面,DBSCAN不要求我们指定集群的数量,避免了异常值,并且在任意形状和大小的集群中工作得非常好。它没有质心,聚类簇是通过将相邻的点连接在一起的过程形成的。

DBSCAN是如何实现的呢?

首先,让我们定义Epsilon和最小点、应用DBSCAN算法时需要的两个参数以及一些额外的参数。

1. Epsilon (ɛ):社区的最大半径。如果数据点的相互距离小于或等于指定的epsilon,那么它们将是同一类的。换句话说,它是DBSCAN用来确定两个点是否相似和属于同一类的距离。更大的epsilon将产生更大的簇(包含更多的数据点),更小的epsilon将构建更小的簇。一般来说,我们喜欢较小的值是因为我们只需要很小一部分的数据点在彼此之间的距离内。但是如果太小,您会将集群分割的越来越小。

1. 最小点(minPts):在一个邻域的半径内minPts数的邻域被认为是一个簇。请记住,初始点包含在minPts中。一个较低的minPts帮助算法建立更多的集群与更多的噪声或离群值。较高的minPts将确保更健壮的集群,但如果集群太大,较小的集群将被合并到较大的集群中。

如果"最小点"= 4,则在彼此距离内的任意4个或4个以上的点都被认为是一个簇。

其他参数

核心点:核心数据点在其近邻距离内至少有的最小的数据点个数。

我一直认为DBSCAN需要一个名为"core_min"的第三个参数,它将确定一个邻域点簇被认为是聚类簇之前的最小核心点数量。

边界点:边界数据点位于郊区,就像它们属于近邻点一样。(比如w/在epsilon距离内的核心点),但需要小于minPts。

离群点:这些点不是近邻点,也不是边界点。这些点位于低密度地区。

13b268302d0ca7804aa1336fc873de38.png

首先,选择一个在其半径内至少有minPts的随机点。然后对核心点的邻域内的每个点进行评估,以确定它是否在epsilon距离内有minPts (minPts包括点本身)。如果该点满足minPts标准,它将成为另一个核心点,集群将扩展。如果一个点不满足minPts标准,它成为边界点。随着过程的继续,算法开始发展成为核心点"a"是"b"的邻居,而"b"又是"c"的邻居,以此类推。当集群被边界点包围时,这个聚类簇已经搜索完全,因为在距离内没有更多的点。选择一个新的随机点,并重复该过程以识别下一个簇。

d3fa367b0d9971b51941016a94583313.png

如何确定最优的Epsilon值

估计最优值的一种方法是使用k近邻算法。如果您还记得的话,这是一种有监督的ML聚类算法,它根据新数据点与其他"已知"数据点的距离来聚类。我们在带标记的训练数据上训练一个KNN模型,以确定哪些数据点属于哪个聚类。当我们将模型应用到新数据时,算法根据与训练过的聚类的距离来确定新数据点属于哪一个聚类。我们必须确定"k"参数,它指定在将新数据点分配给一个集群之前,模型将考虑多少个最邻近点。

为了确定最佳的epsilon值,我们计算每个点与其最近/最近邻居之间的平均距离。然后我们绘制一个k距离,并选择在图的"肘部"处的epsilon值。在y轴上,我们绘制平均距离,在x轴上绘制数据集中的所有数据点。

如果选取的epsilon太小,很大一部分数据将不会被聚类,而一个大的epsilon值将导致聚类簇被合并,大部分数据点将会在同一个簇中。一般来说,较小的值比较合适,并且作为一个经验法则,只有一小部分的点应该在这个距离内。

如何确定最佳minPts

通常,我们应该将minPts设置为大于或等于数据集的维数。也就是说,我们经常看到人们用特征的维度数乘以2来确定它们的minPts值。

就像用来确定最佳的epsilon值的"肘部方法"一样,minPts的这种确定方法并不是100%正确的。

DBSCAN聚类的评价方式

影像法:该技术测量集群之间的可分离性。首先,找出每个点与集群中所有其他点之间的平均距离。然后测量每个点和其他簇中的每个点之间的距离。我们将两个平均值相减,再除以更大的那个平均值。

我们最终想要的是一种较高(比如最接近1)的分数,表明存在较小的簇内平均距离(紧密簇)和较大的簇间平均距离(簇间分离良好)。

集群可视化解释:获得集群之后,解释每个集群非常重要。这通常是通过合并原始数据集和集群并可视化每个集群来完成的。每个集群越清晰越独特越好。我们将在下面实现这个过程。

DBSCAN的优点

· 不需要像KMeans那样预先确定集群的数量

· 对异常值不敏感

· 能将高密度数据分离成小集群

· 可以聚类非线性关系(聚类为任意形状)

DBSCAN的缺点

· 很难在不同密度的数据中识别集群

· 难以聚类高维数据

· 对极小点的参数非常敏感

让我们尝试一下

import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport seaborn as snsimport plotly.offline as pyopyo.init_notebook_mode()import plotly.graph_objs as gofrom plotly import toolsfrom plotly.subplots import make_subplotsimport plotly.offline as pyimport plotly.express as pxfrom sklearn.cluster import DBSCANfrom sklearn.neighbors import NearestNeighborsfrom sklearn.metrics import silhouette_scorefrom sklearn.preprocessing import StandardScalerfrom sklearn.decomposition import PCAplt.style.use('fivethirtyeight')from warnings import filterwarningsfilterwarnings('ignore')with open('HR_data.csv') as f:    df =  pd.read_csv(f, usecols=['satisfaction_level', 'last_evaluation', 'number_project',       'average_montly_hours', 'time_spend_company', 'Work_accident',       'promotion_last_5years'])f.close()
d8e4b22f962f20a484701e94b2d84c6e.png

1. 标准化

由于数据集中的特特征不在相同的范围内,所以我们需要对整个数据集进行标准化。换句话说,我们数据集中的每个特征对于它们的数据都有独特的大小和范围。满意度水平增加一分并不等于最后评价增加一分,反之亦然。由于DBSCAN利用点之间的距离(欧几里得)来确定相似性,未缩放的数据会产生问题。如果某一特征在其数据中具有较高的可变性,则距离计算受该特征的影响较大。通过缩放特征,我们将所有特征对齐到均值为0,标准差为1。

scaler = StandardScaler()scaler.fit(df)X_scale = scaler.transform(df)df_scale = pd.DataFrame(X_scale, columns=df.columns)df_scale.head()
ad612364d26055999817c6c7c8e23f67.png

2. 特征降维

在一些算法如KMeans中,如果数据集的特征维度太大,就很难精确地构建聚类。高维数并不一定意味着成百上千维度的特征。甚至10个维度的特征也会造成准确性问题。

特征降维背后的理论是将原始特征集转换为更少的人工派生特征,这些特征仍然保留了原始特征中包含的大部分信息。

最流行的特征降维技术之一是主成分分析(PCA)。PCA将原始数据集缩减为指定数量的特征,并将这些特征称为主成分。我们必须选择我们希望看到的主成分的数量。我们在我关于KMeans集群的文章中讨论了减少特性,我强烈建议您看一看()。

首先,我们需要确定适当的主成分数量。3个主成分似乎占了大约75%的方差。

pca = PCA(n_components=7)pca.fit(df_scale)variance = pca.explained_variance_ratio_ var=np.cumsum(np.round(variance, 3)*100)plt.figure(figsize=(12,6))plt.ylabel('% Variance Explained')plt.xlabel('# of Features')plt.title('PCA Analysis')plt.ylim(0,100.5)plt.plot(var)
f64f58108ada29ad7c78f5b01be262c2.png

现在我们知道了维持一个特定百分比的方差所需的主成分的数量,让我们对原始数据集应用一个3成分的主成分分析。请注意,第一个主成分占到与原始数据集方差的26%。在本文的其余部分中,我们将使用"pca_df"数据框架。

pca = PCA(n_components=3)pca.fit(df_scale)pca_scale = pca.transform(df_scale)pca_df = pd.DataFrame(pca_scale, columns=['pc1', 'pc2', 'pc3'])print(pca.explained_variance_ratio_)
450b1a8d29aeb38022885f1f01d8eec0.png

在3D空间中绘制数据,可以看到DBSCAN存在一些潜在的问题。DBSCAN的一个主要缺点就是它不能准确地对不同密度的数据进行聚类,从下面的图中,我们可以看到两个不同密度的单独集群。在应用DBSCAN算法时,我们可能能够在数据点较少的聚类结果中找到不错的聚类方式,但在数据点较多的聚类中的许多数据点可能被归类为离群值/噪声。这当然取决于我们对epsilon和最小点值的选择。

Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(colorscale='Greys', opacity=0.3, size = 10, ))layout = go.Layout(margin=dict(l=0,r=0),scene = Scene, height = 1000,width = 1000)data = [trace]fig = go.Figure(data = data, layout = layout)fig.show()
e9f3af81dd361129ff2cfe279d8536fa.png

3.DBSCAN聚类

方法1

在应用聚类算法之前,我们必须使用前面讨论过的"肘形法"来确定合适的epsilon级别。看起来最佳的值在0.2左右。最后,由于我们的数据有3个主成分,我们将把最小点标准设置为6。

plt.figure(figsize=(10,5))nn = NearestNeighbors(n_neighbors=5).fit(pca_df)distances, idx = nn.kneighbors(pca_df)distances = np.sort(distances, axis=0)distances = distances[:,1]plt.plot(distances)plt.show()
91234398c634d7716ab35173fae89acb.png

将epsilon设置为0.2,将min_samples设置为6,得到了53个集群,影像分数为-0.521,以及超过1500个被认为是离群值/噪声的数据点。在某些研究领域,53个集群可能被认为是有用的,但我们有一个15000名员工的数据集。从业务的角度来看,我们需要一些可管理的集群(即3-5个),以便更好地分配工作场所。此外,剪影得分-0.521表明数据点是不正确的聚集。

看看下面的3D图,我们可以看到一个包含了大多数数据点的集群。出现了一个较小但很重要的聚类簇,但剩下52个聚类簇的规模要小得多。从业务角度来看,这些集群提供的信息不是很多,因为大多数员工只属于两个集群。组织希望看到几个大的集群,以确定它们的有效性,但也能够从事一些针对集群员工的组织主动性工作(例如。增加培训、薪酬变化等)。

db = DBSCAN(eps=0.2, min_samples=6).fit(pca_df)labels = db.labels_# Number of clusters in labels, ignoring noise if present.n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)n_noise_ = list(labels).count(-1)print('Estimated number of clusters: %d' % n_clusters_)print('Estimated number of noise points: %d' % n_noise_)print("Silhouette Coefficient: %0.3f" % metrics.silhouette_score(pca_df, labels))
88184374b500de3d6519248fbcff9917.png
Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))labels = db.labels_trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color = labels, colorscale='Viridis', size = 10, line = dict(color = 'gray',width = 5)))layout = go.Layout(scene = Scene, height = 1000,width = 1000)data = [trace]fig = go.Figure(data = data, layout = layout)fig.update_layout(, font=dict(size=12,))fig.show()Image for post
57717c2712e6df56fc8f1c4a4d85173f.png

方法2

我们不使用"肘部方法"和最小值启发式方法,而是使用迭代方法来微调我们的DBSCAN模型。在对数据应用DBSCAN算法时,我们将迭代一系列的epsilon和最小点值。

在我们的例子中,我们将迭代0.5到1.5之间的epsilon值和2-7之间的minPts。for循环将使用这组值运行DBSCAN算法,并为每次迭代生成集群数量和影像分数。请记住,您需要根据数据调整参数。您可能会在一组参数上运行此代码,并发现产生的最佳影像分数是0.30。为了将更多的点包含到一个集群中,您可能需要增加值。

pca_eps_values = np.arange(0.2,1.5,0.1) pca_min_samples = np.arange(2,5) pca_dbscan_params = list(product(pca_eps_values, pca_min_samples))pca_no_of_clusters = []pca_sil_score = []pca_epsvalues = []pca_min_samp = []for p in pca_dbscan_params:    pca_dbscan_cluster = DBSCAN(eps=p[0], min_samples=p[1]).fit(pca_df)    pca_epsvalues.append(p[0])    pca_min_samp.append(p[1])pca_no_of_clusters.append(len(np.unique(pca_dbscan_cluster.labels_)))    pca_sil_score.append(silhouette_score(pca_df, pca_dbscan_cluster.labels_))pca_eps_min = list(zip(pca_no_of_clusters, pca_sil_score, pca_epsvalues, pca_min_samp))pca_eps_min_df = pd.DataFrame(pca_eps_min, columns=['no_of_clusters', 'silhouette_score', 'epsilon_values', 'minimum_points'])pca_ep_min_df
9249a36b40b999929d0ce9525ecd3269.png

我们可以看到,通过我们的epsilon和minPts的迭代,我们已经获得了很大范围的簇数和影像分数。0.9到1.1之间的epsilon分数开始产生可管理的集群数量。将epsilon增加到1.2或更高会导致集群数量太少,无法在商业上发挥作用。此外,其中一些集群可能只是噪音。我们稍后会讲到。

增加的epsilon会减少集群的数量,但每个集群也会开始包含更多的离群点/噪声数据点,这一点也可以理解为有一定程度的收益递减。

为了简单起见,让我们选择7个集群并检查集群分布情况。(epsilon: 1.0和minPts: 4)。

同样重要的是,运行此代码串时肯定会遇到的一个常见错误。有时,当你设置的参数不合适,for循环最终会变成epsvalues和minsamples的组合,这只会产生一个集群。但是,silhouette ette_score函数至少需要定义两个集群。您需要限制参数以避免此问题。

在上面的示例中,如果我们将epsilon参数的范围设置为0.2到2.5,那么很可能会生成一个集群并最终导致错误。

0ad82072c483a31f92e4eb25ddd1dd42.png

你可能会问自己"我们不是应该获得7个集群吗?"答案是肯定的,如果我们看一下独特的标签/集群,我们看到每个数据点有7个标签。根据Sklearn文档,标签"-1"等同于一个"嘈杂的"数据点,它还没有被聚集到6个高密度的集群中。我们自然不希望将任何"-1"标签考虑为一个集群,因此,它们将从计算中删除。

db = DBSCAN(eps=1.0, min_samples=4).fit(pca_df)labels = db.labels_# Number of clusters in labels, ignoring noise if present.n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)n_noise_ = list(labels).count(-1)print('Estimated number of clusters: %d' % n_clusters_)print('Estimated number of noise points: %d' % n_noise_)print("Silhouette Coefficient: %0.3f" % silhouette_score(pca_df, labels))
9bf1824e3bb650626e54a0e4ee7d8ed8.png
set(labels)
403872efe6551708f6a84efe816aa576.png

从6个DBSCAN派生集群的3D图中可以看出,尽管密度较小,但位于图顶端的密度较小的集群对DBSCAN并没有造成太大影响。如果您还记得的话,DBSCAN很难正确地集群各种密度的数据。顶部的集群和更大的底部集群之间的距离很可能大于1.0的epsilon值。

也就是说,数据集包含额外的高密度集群,但是我们的epsilon和minPts太大了。底部的聚类簇包含至少两个高密度的聚类簇,然而,由于底部聚类簇的高密度降低了epsilon和minPts,只会产生许多更小的聚类簇。这也是DBSCAN的主要缺点。我一直认为DBSCAN需要第三个参数"min_core",它将确定一个集群可以被视为有效集群之前的最小核心点数量。

4acc78a99be9e014eb0e52a4b396f453.png
Scene = dict(xaxis = dict(title  = 'PC1'),yaxis = dict(title  = 'PC2'),zaxis = dict(title  = 'PC3'))# model.labels_ is nothing but the predicted clusters i.e y_clusterslabels = db.labels_trace = go.Scatter3d(x=pca_df.iloc[:,0], y=pca_df.iloc[:,1], z=pca_df.iloc[:,2], mode='markers',marker=dict(color = labels, colorscale='Viridis', size = 10, line = dict(color = 'gray',width = 5)))layout = go.Layout(scene = Scene, height = 1000,width = 1000)data = [trace]fig = go.Figure(data = data, layout = layout)fig.update_layout(DBSCAN Clusters (6) Derived from PCA'", font=dict(size=12,))fig.show()

在我们开始之前,让我们快速了解一下每个集群中的员工数量。似乎cluster 0包含了大部分信息不太丰富的数据点。事实上,如果我们使用0.5的epsilon值和5的minPts运行算法,就会产生63个集群,集群0仍然会包含99%的员工人口。

np.unique(labels, return_counts=True)
f310c466fb07dfb7c5c4cb298ab04590.png

小结

DBSCAN,一种密度聚类算法,常用于非线性或非球面数据集。epsilon和minPts是两个必需的参数。epsilon是附近数据点的半径,这些数据点需要被认为是足够"相似"才能开始聚类。最后,minPts是需要在半径内的数据点的最小数目。

在我们的示例中,我们试图根据工作特征对包含15,000名员工的数据集进行聚类。我们首先标准化了数据集以缩放特征。接下来,我们应用主成分分析将维度/特征的数量减少到3个主成分。使用"肘部法",我们估计了0.2的epsilon值和6的minPts。使用这些参数,我们能够获得53个集群,1500个离群值和-0.52的影响分数。不用说,结果并不是很理想。

接下来,我们尝试了一种迭代的方法来微调epsilon和minPts。我们已经确定了epsilon值为1.0和minPts值为4。该算法返回6个有效的集群(一个-1集群),只有7个异常值,以及0.46的可观影像分数。然而,在绘制派生集群时,发现第一个集群包含99%的员工。从业务的角度来看,我们希望我们的集群能够更加均衡地分布,从而为我们提供关于员工的良好见解。

DBSCAN似乎不是这个特定数据集的最佳聚类算法。

作者:Kamil Mysiak

deephub翻译组:孟翔杰

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Arrays.asList 使用细节

通常初始化后使用如下,但是报错 UnsupportOperationException.... 根据提示信息,就是调用add()方法时抛出了异常。顺着堆栈信息往上找,提示的是AbstractList类的108行出了异常,这一行所在方法的具体实现如下: //108行 …

python list元素合并_python list 合并连接字符串的方法

python list 合并连接字符串的方法 更新时间:2013年03月09日 22:02:18 作者: python 列表合并字符串,我们一般会用到字符串的join方法来操作。下面通过代码的形式,详细的说下list怎么拼成字符串? 相关文章这篇文章主要…

单片机按键防抖程序_这些单片机按键设计方案,请拿好,不谢!

在单片机系统里,按键是常见的输入设备,在本文中介绍几种按键硬件、软件设计方面的技巧。一般的在按键的设计上,一般有四种方案,创客学院带你零基础学习电子产品设计。一是GPIO口直接检测单个按键,如图1.1所示;二是按键…

Oracle 11G 安装详解

oracle官网下载地址:http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 官网下载需要注册orcale账号,比较繁琐,这里直接放已经下载好的安装包链接 Oracle11G下载链接: https://pan.baidu.com/s/1v6oD4jAt…

kubeadm部署k8s_用 kubeadm 部署生产级 k8s 集群

概述kubeadm 已⽀持集群部署,且在1.13 版本中 GA,⽀持多 master,多 etcd 集群化部署,它也是官⽅最为推荐的部署⽅式,⼀来是由它的 sig 组来推进的,⼆来 kubeadm 在很多⽅⾯确实很好的利⽤了 kubernetes 的许…

统计学习方法概论---分类问题

为什么80%的码农都做不了架构师?>>> 分类问题 转载于:https://my.oschina.net/liyangke/blog/2945185

CENTOS7 Python3.7 PyAudio 安装

2019独角兽企业重金招聘Python工程师标准>>> 出现错误: gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -fPIC -fPIC -I/usr/local/python371/include/python3.7m -c src/_portaudiomodule.c -o build/temp.linux-aarch64-3.7/src/…

bash for循环_Bash 中的 For 循环

循环是编程语言的基本概念之一。当你想要一遍又一遍地运行一系列命令直到达到某个条件后终止退出时,循环很方便。在诸如 Bash 之类的脚本语言中,循环对于自动执行重复性任务非常有用。在 Bash 脚本中有3个基本的循环结构,for 循环&#xff0c…

linux 信号_Linux的信号和线程

Linux的信号和线程-Tech Talk 让技术发出声音​www.ttalk.im什么是线程线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC)&#xff0…

python 数据结构

一. 深入链表 先来介绍一些链表具备的一些常用方法: append(x) : 把一个元素添加到链表的结尾 extend(L) : 将另外一个链表合并到该链表中 insert(i,x) : 插入一个元素到指定位置的前面 remove(x) : 删除链表中第一个值为x的元素 如果没有这样的元素 则返回错误 pop…

go语言项目优化(经验之谈)

1 Go的应用场景 在斗鱼我们将GO的应用场景分为以下三类,缓存类型数据,实时类型数据,CPU密集型任务。这三类应用场景都有着各自的特点。 ● 缓存类型数据在斗鱼的案例就是我们的首页,列表页,这些页面和接口的特点是不同…

python交互界面用图片当背景_wxPython实现窗口用图片做背景

本文实例为大家分享了wxPython实现窗口用图片做背景的具体代码,供大家参考,具体内容如下 效果图:实现代码: #!/usr/bin/env python # -*- encoding:utf-8 -*- import wx class MyPanel(wx.Panel): def __init__(self,parent,id): …

c 字符串转数字_C语言实现十进制转216进制、十六进制转十进制

1、十进制转2~16进制【问题描述】从键盘输入十进制整数num及转换的进制数base,将整数num转换为base进制(base取值范围为 2~16)。方法为:十进制数除base取余法,即十进制数除以base,余数为权位上的数&#xf…

一个简单的LINQ TO XML, AJAX 例子[译]

这个教程是用Visual Studio.net 2008建立,也可以使用VS2005,但你需要从这里下载安装Microsofts ASP.NET AJAX Extensions,AJAX和LINQ是微软目前主要焦点,两个看上去不足为奇,但背后都隐藏着巨大的潜力和力量。在这个示…

python3性能还低吗_Python3 vs. Python2 大作战,谁将是性能之王?

渲染 HTML 模板 django_html 测试将使用 Django 模板渲染引擎来构建一个 150x150 的 HTML 表格。 它利用了 Django 引擎的 Content 和 Template 类。如图所示,Python 3.7 比 Python 2.7 快 1.19 倍,但除此之外,其他 Python 3 版本都没有 Pyth…

python day08

一 文件处理补充 控制文件中光标移动 1 f.read(n): l.文件打开方式为文本模式的时,代表读取N个字符 ll.文件打开方式为b模式时,读取N个字节 强调:只有在read(n)模式下 N代表字符个数,除此之外的是以字节为单位 2 f.seek(): 光标移动是以字节为单位的整数移动. 三种模式:(分别为…

VSCode 小鸡汤 第00期 —— 安装和入门

简介 这将是一个新的系列,将会以 Visual Studio Code(后文都简称为 VSCode 啦)的操作,环境配置,插件介绍为主,为大家不定期的介绍 VSCode 的一些操作技巧,所以取名 VSCode 小鸡汤,本…

一次缓存性能问题排查

概述以下分享的都跳过了很多坑,包括redis、tomcat环境配置、机器硬件配置等等问题(与线上保持一致,或者硬件性能减配系数,例如线上:8C16G,压测:4C8G,系数简单相差2倍)&am…

再读新疆系列(六)——吹拂“卡拉库里湖”的风

一下飞机,导游王雪作了简短的自我介绍,马不停蹄地带着我们经喀什市区直接向帕米尔高原的“卡拉库里”湖走。 问午饭在哪吃? 答:“湖边”。 “几点能到?” “大约下午二点多。”妈呀,又经历一次残酷的饥饿历…