【数据物语系列】 漫谈数据分布可视化分析

news2025/2/28 20:10:27
【数据物语系列】 漫谈数据分布可视化分析
FesianXu 20221125 at Baidu Search Team

前言

在实际工作中,我们经常会遇到一堆数据,对数据的有效分析至为关键,而数据的分布就是一种非常重要的数据属性,需要通过合适的可视化手段进行分析。本文参考[1],基于seaborn库介绍一些常用的数据分布可视化方法。如有谬误请联系指出,本文遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明并且联系笔者,谢谢

∇ \nabla 联系方式:

e-mail: FesianXu@gmail.com

github: https://github.com/FesianXu

知乎专栏: 计算机视觉/计算机图形理论与应用

本文实验代码库: https://github.com/FesianXu/visualization_analysis_methods

公众号:机器学习杂货铺3号店


数据的分布,我们可以理解为是“数据的形状”。一个“完美”的数据分布,会将数据所有可能的数据点都囊括其中,因此数据的分布表征了不同数据之间的本质区别。然而现实生活的数据不可能对所有可能的数据点都进行遍历(因为通常会有无限个数据点),因此我们通常都是在某个采样的子集中,尝试对数据本原的分布进行分析。常见的数据分布可视化方法有以下几种:

  1. 直方图(Histogram)
  2. 条件直方图(Conditional Histogram)
  3. 核密度估计图(Kernel Density Estimation,KDE)
  4. 累积分布函数图(Empirical Cumulative Distribution Function, ECDF)
  5. 箱型图(boxplot)
  6. 提琴图(violin plot)
  7. 二元直方图(bivariate histogram)
  8. 联合概率分布曲线(Joint Distribution Plot)
  9. 边缘概率分布曲线(Marginal Distribution Plot)

如Fig 1.所示,我们以penguins数据集为例子分别进行介绍。

penguins

Fig 1. penguins数据集,一共有344条数据,每条数据有7个维度的属性。

单变量直方图

单变量直方图(univariate histogram)是一种单变量的分布可视化方法,将所有数据点进行分桶,然后统计落在某个桶里的数据点的频次,以柱形图的形式将每个桶的频次绘制出来。如Fig 1.1所示,我们对penguins数据中的flipper_length_mm属性进行直方图绘制。

import seaborn as sns
data = sns.load_dataset("penguins", data_home="./data/seaborn-data")
# 可以挑选不同的分桶数量bins,或者每个桶的宽度
ret = sns.displot(data, x='flipper_length_mm', bins=20)
ret = sns.displot(data, x='flipper_length_mm', bins=50)
ret = sns.displot(data, x='flipper_length_mm', binwidth=5)

histogram_univariate

Fig 1.1 对penguins数据的`flipper_length_mm`属性进行绘制直方图,从左到右,分别是(a)分桶数是20,(b)分桶数50,(c)分桶宽度是5。

我们发现,选取不同的分桶数量和分桶宽度对于整个分布可视化结果影响很大。分桶越多,分布越细致,但也越容易被某些噪声影响我们分析整体分布趋势,一般在实际中我们通常会选取多个分桶数进行尝试。原始的直方图统计的是分桶中的数据频次,不同数据的总数不同因此频次并不可比,通常可以考虑进行归一化处理。如Fig 1.2所示,通常有两种类型的归一化:密度归一化,概率归一化。密度归一化指的是所有柱形面积和为1,概率归一化指的是所有柱形的高度和为1。密度归一化的情况下,由于纵坐标的数值会受到横坐标数值尺度的影响,通常是不可比,而概率归一化不需要考虑横坐标的数值尺度,因此通常是可比的。

ret = sns.displot(data, x='flipper_length_mm', bins=20, stat='density') # 密度归一形式的归一化
ret = sns.displot(data, x='flipper_length_mm', bins=20, stat='probability') # 概率归一形式的归一化

norm_histogram

Fig 1.2 (a) 密度归一形式的归一化; (b)概率归一形式的归一化。

我们既可以对连续变量进行直方图统计,也可以对离散变量进行直方图统计,如Fig 1.3所示,我们通过设置shrink参数,可以控制柱形的宽度,使得可视化效果更像是一个离散变量的直方图。

tips = sns.load_dataset('tips')
ret = sns.displot(tips, x='day', stat='probability')
ret = sns.displot(tips, x='day', stat='probability', shrink=.8)

discrete_hist

Fig 1.3 (a)shrink=1.0的情况,柱形之间“肩靠肩”,没有间隙;(b)通过设置shrink=0.8,可以使得离散变量的柱形之间存在间隔,看起来更“离散”一些,与连续变量直方图有所区别。

条件直方图

再回到Fig 1.2,我们能明显地发现这个分布有明显的两个峰,这个flipper_length_mm代表的是企鹅的鳍肢的长度,这个属性会受到其他什么属性的影响呢?在之前的直方图中,我们绘制的是概率分布 P ( X ) P(X) P(X),如今我们需要绘制条件概率分布 P ( X ∣ Y ) P(X|Y) P(XY),以考察到底是其他哪些属性影响了企鹅的鳍肢的长度。如Fig 2.1所示,由于笔者觉得种类,性别,和居住的岛屿可能会影响到企鹅的鳍肢长度,我绘制了 P ( f l i p p e r _ l e n g t h _ m m ∣ s p e c i e s ) P(\mathrm{flipper\_length\_mm | species}) P(flipper_length_mmspecies) P ( f l i p p e r _ l e n g t h _ m m ∣ s e x ) P(\mathrm{flipper\_length\_mm | sex}) P(flipper_length_mmsex) P ( f l i p p e r _ l e n g t h _ m m ∣ i s l a n d ) P(\mathrm{flipper\_length\_mm | island}) P(flipper_length_mmisland)的几种条件分布。从Fig 2.1(a)可以发现企鹅的种类的确有所影响(Adelie种类和Gentoo种类的企鹅的鳍肢分布显著不同),而雌性雄性企鹅的鳍肢长度都呈现双峰分布,因此并不是导致Fig 1.2中出现双峰分布的原因,同理,从Fig 2.1(c)中可以发现企鹅居住的岛屿也是导致出现双峰的原因。这些条件分布都可以通过设置displot()中的hue参数实现。

ret = sns.displot(data, x="flipper_length_mm", hue='species')
ret = sns.displot(data, x="flipper_length_mm", hue='sex')
ret = sns.displot(data, x="flipper_length_mm", hue='island')

conditional_hist

Fig 2.1 (a)-(c)是不同的条件分布直方图。

但是居住地会影响企鹅的鳍肢生长发育,这一点比较奇怪,可能并不是一个直接原因,也许是不同岛屿居住的企鹅种类不同导致的?我们可以绘制 P ( i s l a n d ∣ s p e c i e s ) P(\mathrm{island|species}) P(islandspecies)条件分布进行考察,如Fig 2.2所示,其中的(a)是一般形式的条件分布柱形图,我们发现不同条件下的柱形会存在层叠,容易看不清楚,此时可以通过设置multiple="stack"将其设置为stack模式,柱形图之间以堆叠形式呈现,不会存在层叠。我们可以发现在Fig 2.1(c)中的Biscoe和Dream岛屿呈现的两个峰,来自于这两个岛屿中的两大企鹅种群——Gentoo,Chinstrap+Adelie(这两个种类的分布较为接近)分布导致。也就是说,鳍肢和企鹅种类的关联才是本质的因果关系。

ret = sns.displot(data, x="island", hue='species')
ret = sns.displot(data, x="island", hue='species', multiple="stack", discrete=False)

island_species_condition

Fig 2.2 (a)一般形式的条件分布绘制,有时候由于柱形图的层叠,容易看不出清楚,此时可以采用stack模式,如(b)所示,此时不同柱形之间不会有层叠。

我们在Fig 1.2中说到过直方图的归一化,由于Fig 1.2中是单变量的分布归一化,因此体现到图中只是纵坐标的尺度变化,而整个图的形状是不会有变化的。在条件直方图中,我们可以将common_norm设置为False,此时进行归一化会将不同条件下的条件分布进行独立的归一化,如Fig 2.3所示,其中(a)和(b)只有纵坐标上的区别,而(c)是将不同条件下的条件分布进行各自的归一化。

ret = sns.displot(data, x="flipper_length_mm", hue='species')
ret = sns.displot(data, x="flipper_length_mm", hue='species', stat="probability")
ret = sns.displot(data, x="flipper_length_mm", hue='species', stat="probability", common_norm=False)

norm_conditional_hist

Fig 2.3 (a)条件分布原图;(b)对条件分布进行归一化,不考虑不同条件下的区别;(c)进行不同条件下的分别归一化。

核密度估计曲线

直方图对数据进行分箱后,统计每个箱子中的数据点频次,因此绘制出来的直方图是离散的柱形图,即便数据是连续型数据。有什么方法可以更好地体现数据的连续性质呢?核密度估计(Kernel Density Estimation,KDE)是一种可行的方法,我们假设每个数据点都是对数据分布的一次随机采样,采样自均值为观察值 x i x_i xi,方差为 σ 2 \sigma^2 σ2的核分布,如公式(3-1)所示,我们对所有数据点的核密度估计曲线进行叠加,得到整个数据分布的核密度估计曲线。我们的核分布通常可以采用高斯分布,如公式(3-2)所示。
f ^ σ 2 ( x ) = 1 n ∑ i = 1 n K σ 2 ( x − x i ) (3-1) \hat{f}_{\sigma^2}(x) = \dfrac{1}{n}\sum_{i=1}^{n} K_{\sigma^2}(x-x_i) \tag{3-1} f^σ2(x)=n1i=1nKσ2(xxi)(3-1)

K σ 2 ( x ) = 1 2 σ exp ⁡ ( − x 2 / ( 2 σ 2 ) ) (3-2) K_{\sigma^2}(x) = \dfrac{1}{\sqrt{2}\sigma} \exp(-x^2/(2\sigma^2)) \tag{3-2} Kσ2(x)=2 σ1exp(x2/(2σ2))(3-2)

如Fig 3.1所示,在给定了6个观察值,绘制出的直方图如Fig 3.1(a)所示,如Fig 3.1(b)所示,其中的红色曲线表示每个样本的高斯核密度估计,叠加起来得到蓝色曲线,为整个数据分布的核密度估计曲线。

样本123456
观察值-2.1-1.3-0.41.95.16.2

kde_plot

Fig 3.1 (a)直方图;(b)对每个样本进行核密度估计,然后叠加得到数据分布的拟合曲线。

回到我们的seaborn,我们通过设置参数kind="kde"进行设置,同时可以通过bw_adjust控制其方差,我们通常把此处的方差称之为带宽(bandwidth)。如Fig 3.2所示,我们发现不同的带宽下,核密度估计曲线的形状天差地别,Fig 3.2(b)中,过小的带宽可以看到分布的更多细节,但是也会收到更多数据噪声的影响,出现过多的毛刺。如Fig 3.2(c)所示,过大的带宽会使得曲线过于平滑,使得一些分布细节被掩饰了,比如其中的双峰分布就被平滑得看不出来了。

sns.displot(data, x="flipper_length_mm", kind="kde", bw_adjust=1)
sns.displot(data, x="flipper_length_mm", kind="kde", bw_adjust=0.25)
sns.displot(data, x="flipper_length_mm", kind="kde", bw_adjust=1.5)

kde_bw_adjust

Fig 3.2 不同的带宽参数对于核密度估计函数曲线的影响。

当然,核密度估计也可以在条件分布的情况下使用,如Fig 3.3所示,同样有几种不同的参数配置曲线的显式效果。

sns.displot(data, x="flipper_length_mm", hue="species", kind="kde")
sns.displot(data, x="flipper_length_mm", hue="species", kind="kde", multiple="stack")
sns.displot(data, x="flipper_length_mm", hue="species", kind="kde", fill=True)

kde_conditional_plot

Fig 3.3 (a) 条件分布下的核密度估计曲线;(b)stack模式的条件分布核密度估计曲线;(c)填充曲线下面积的条件分布核密度估计曲线。

可以将直方图和核密度估计曲线绘制在同一张图中以便于分析,如Fig 3.4所示。

sns.displot(data, x="flipper_length_mm", kde=True)
sns.displot(data, x="flipper_length_mm", hue="species", kde=True)

hist_and_kde

Fig 3.4 将直方图和核密度估计曲线绘制在同一张图中。

箱型图

直方图和核密度估计都太“重”了,很多时候在刚接触某个数据集的时候,一些统计性指标就足够让我们对这份数据有足够的了解。常用的统计指标有:中位数(50分位线数),均值,方差,25分位线数,75分位线数等,而这些指标大多数情况可以从箱型图(Boxplot)中一目了然。如Fig 4.1所示,一个箱型图由五根线构成,Q1是25分位线,Q3是75分位线,指的是将数据从低到高排序(升序),前25%称之为25分位线,前75%称之为75分位线。Q3-Q1称之为四分位距(Inter Quartile Range,IQR),Q2表示50分位线,也即是中位线,小于Q1-1.5IQR 和 大于 Q3+1.5IQR的数据称之为离群点。

BVoxplot

Fig 4.1 箱型图的几种基本分位线。

如Fig 4.2所示,我们可以用seaborn绘制箱型图,其中用红点表示均值,可以发现Fig 4.2(a)其实绘制了 P ( f l i p p e r _ l e n g t h _ m m ∣ s p e c i e s ) P(\mathrm{flipper\_length\_mm|species}) P(flipper_length_mmspecies)条件分布下的箱型图,当然也可以和Fig 4.2(c)一样绘制单变量的箱型图,这种也是我们最常见到的形式。如Fig 4.2(b)所示,我们还可以绘制2个条件下的箱型图,也即是 P ( f l i p p e r _ l e n g t h _ m m ∣ s p e c i e s , s e x ) P(\mathrm{flipper\_length\_mm|species,sex}) P(flipper_length_mmspecies,sex)。通过箱型图,我们可以非常直观地观察到不同数据分布之间的差别,是一种轻量化的数据分布分析方法。

sns.boxplot(data=data, 
            x="flipper_length_mm", y='species', 
            showmeans=True,
            meanprops={"marker":"o",
                       "markerfacecolor":"red", 
                       "markeredgecolor":"black",
                      "markersize":"5"})
sns.boxplot(data=data, 
            x="flipper_length_mm", y='species', hue='sex',
            showmeans=True,
            meanprops={"marker":"o",
                       "markerfacecolor":"red", 
                       "markeredgecolor":"black",
                      "markersize":"5"})
sns.boxplot(data=data, 
            x="flipper_length_mm", 
            showmeans=True,
            meanprops={"marker":"o",
                       "markerfacecolor":"red", 
                       "markeredgecolor":"black",
                      "markersize":"5"})

boxplot

Fig 4.2 (a)箱型图;(b)多个条件下的箱型图;(c)单变量箱型图。

提琴图

箱型图可以提供数据的直观印象,为了进一步分析数据,我们还是需要引入分布曲线。我们希望可以以箱型图的形式,同时把数据分布也可视化出来,这样我们既可以复用箱型图得到的结论,而且可以进一步探索数据分布的细致区别。提琴图(Violin Plot)就是为此设计的,如Fig 5.1所示,其将数据的核密度估计曲线以类似于箱型图的排版进行展示,其中的每条黑色竖线是每个真实的样本点数据。注意到提琴图本质是核密度估计曲线,因此如果样本数据过少其曲线是不准确的,所以通常我们会把样本点也绘制出来(也即是黑色竖线),以判断数据数量是否会过于稀疏导致KDE不置信。

sns.violinplot(data=data, x="flipper_length_mm", y='species', inner="stick")
sns.violinplot(data=data, x="flipper_length_mm", y='species', hue='sex', split=True, inner="stick")
sns.violinplot(data=data, x="flipper_length_mm", inner="stick")

violin_plot

Fig 5.1 提琴图的不同形式,(a)提琴图;(b)两个条件下的提琴图;(c)单变量提琴图。

累积分布函数曲线

直方图需要选择合适的分箱数,而KDE需要选择合适的带宽,否则可能会影响数据分布的可视化效果进而影响分析。有没有一种方法可以不用选择任何参数就能表征数据的分布特性呢?经验累积分布函数(Empirical Cumulative Distribution Function,ECDF)也许是一种可行的选择。累积分布函数(Cumulative Distribution Function,CDF) F X ( x ) F_X(x) FX(x)对概率分布 f X ( x ) f_X(x) fX(x)进行积分或者求和得到,如公式(6-1)所示。当对实际数据进行处理时候,由于我们的数据有限且来自于实际观察,因此我们通常称之为“经验”[2],并且ecdf是采用求和,而不是积分。
F X ( x ) = P ( X ≤ x ) = ∫ − ∞ x f X ( t ) d t (6-1) F_X(x) = P(X \leq x) = \int_{-\infty}^{x}f_X(t) \mathrm{d}t \tag{6-1} FX(x)=P(Xx)=xfX(t)dt(6-1)
如Fig 6.1所示,ecdf曲线是一个单调递增的曲线,其会考虑每一个观察到的数据点,不需要指定其他额外的参数,如Fig 6.1(b)所示,我们也可以绘制条件分布下的ecdf。ECDF的缺点在于不如直方图和核密度估计一样直观地表征了数据分布,但是理论上ECDF同样可以“坍缩”到概率分布,如公式(6-2)所示
f X ( x ) = d F X ( x ) d x (6-2) f_X(x) = \dfrac{\mathrm{d}F_X(x)}{\mathrm{d}x} \tag{6-2} fX(x)=dxdFX(x)(6-2)

sns.displot(data, x="flipper_length_mm", kind="ecdf")
sns.displot(data, x="flipper_length_mm", hue="species", kind="ecdf")

ecdf_plot

Fig 6.1 ECDF曲线,(a)单变量的ECDF曲线;(b)条件分布下的ECDF曲线。

二元直方图

有时候我们需要考察数据的联合概率分布,比如 P ( f l i p p e r _ l e n g t h _ m m , s p e c i e s ) P(\mathrm{flipper\_length\_mm, species}) P(flipper_length_mm,species),此时可以绘制二元直方图。我们可以指定displot()y参数,绘制两元变量的直方图。这种类型的直方图类似于热值图(heatmap),以颜色的深浅表示数值的大小。如Fig 7.1(c)所示,同样可以指定kind参数进而绘制二元核密度估计曲线。在指定了hue的情况下,同样可以实现条件分布的绘制。

sns.displot(data, x="flipper_length_mm", y="species",cbar=True)
sns.displot(data, x="bill_length_mm", y="bill_depth_mm", hue="species")
sns.displot(data, x="bill_length_mm", y="bill_depth_mm", hue="species", kind="kde")

bivariate_hist_kde_plot

Fig 7.1 二元直方图以及二元核密度估计曲线。

联合概率分布 和 边缘概率分布曲线

考察二元变量的联合概率分布,采用散点图(scatter plot)也是一种不错的选择,如Fig 8.1所示,可以将 P ( b i l l _ l e n g t h _ m m , b i l l _ d e p t h _ m m ) P(\mathrm{bill\_length\_mm, bill\_depth\_mm}) P(bill_length_mm,bill_depth_mm)通过散点图的形式进行可视化,直观地考察两个变量之间的相关关系。散点图上面的直方图和右边的直方图分别是 P ( b i l l _ l e n g t h _ m m ) P(\mathrm{bill\_length\_mm}) P(bill_length_mm) P ( b i l l _ d e p t h _ m m ) P(\mathrm{bill\_depth\_mm}) P(bill_depth_mm)分布的直方图,在这种情形下,我们称之为边缘概率分布曲线(Marginal Distribution),其计算公式见(8-1)。
P ( x ) = ∑ y P ( x , y ) (8-1) P(x) = \sum_{y} P(x,y) \tag{8-1} P(x)=yP(x,y)(8-1)
我们也可以对联合概率分布的散点图和边缘概率分布的直方图进行核密度估计,如Fig 8.1(b)所示。

sns.jointplot(data=data, x="bill_length_mm", y="bill_depth_mm")
sns.jointplot(
    data=data,
    x="bill_length_mm", y="bill_depth_mm", hue="species",
    kind="kde"
)

joint_hist_scatter_kde

Fig 8.1 联合概率分布与边缘概率分布的可视化。

通过使用seabornJointGrid功能,可以对联合概率分布和边缘概率分布的表示形式进行自定义组合(散点图,KDE,箱型图等),如Fig 8.2所示。

g = sns.JointGrid(data=data, x="bill_length_mm", y="bill_depth_mm")
g.plot_joint(sns.histplot)
g.plot_marginals(sns.kdeplot)

g = sns.JointGrid(data=data, x="bill_length_mm", y="bill_depth_mm")
g.plot_joint(sns.histplot)
g.plot_marginals(sns.boxplot)

g = sns.JointGrid(data=data, x="bill_length_mm", y="bill_depth_mm")
g.plot_joint(sns.scatterplot)
g.plot_marginals(sns.boxplot)

joint_draw

Fig 8.2 通过JointGrid进行直方图,KDE,散点图,箱型图的组合。

Reference

[1]. https://seaborn.pydata.org/tutorial/distributions.html#plotting-univariate-histograms

[2]. https://blog.csdn.net/LoseInVain/article/details/78746520, 经验误差,泛化误差

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

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

相关文章

【创建springboot-maven项目搭建mybatis框架】(超详细)

目录 1. 创建Spring Boot项目,相关参数 2. 创建数据库 3. 在IntelliJ IDEA中配置Database面板 4. 添加数据库编程的依赖 5. 关于Mybatis框架 6. Mybatis编程:插入相册数据 1. 创建Spring Boot项目,相关参数 项目名称:csmall…

[附源码]java毕业设计中小企业人力资源管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

javaEE飞机航班信息查询网站系统

本系统主要包含了订票管理、航班信息管理、站内新闻管理、活动信息管理、用户信息管理、留言等多个功能模块。下面分别简单阐述一下这几个功能模块需求。 管理员的登录模块:管理员登录系统后台对本系统其他管理模块进行管理。 添加管理员模块:向本系统中…

UE5笔记【十】第一个蓝图项目:bluePrint。

我们将上升的斜坡或者楼梯隐藏,往下移动,使其隐藏在地面以下。然后将方块也向下移动,漏出一点来。我们要模拟的场景是:当人移动到蓝色方块上时,踩在方块上,上升的楼梯升起来。然后人可以上楼。 将蓝色方块…

HTML静态网页作业——电影介绍-你的名字 5页 无js 带音乐

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

基于双层优化的微电网系统规划设计方法matlab程序(yalmip+cplex)

基于双层优化的微电网系统规划设计方法matlab程序(yalmipcplex) 参考文献:基于双层优化的微电网系统规划设计方法 摘要:规划设计是微电网系统核心技术体系之一。从分布式电源的综合优化(组合优化、容量优化)和分布式电源间的调度…

【虚幻引擎UE】UE5 两种球体绘制方法

一、网格球体绘制 center 中心点向量 segments参数越大,线条越多 radius是球体半径 thickness 厚度可以不用管 Depth Priority 是渲染深度可以不用管 F Life Time 是持续时间 C代码如下—— .cpp #include "drawBallFunc.h" #include "Components…

机器学习中的数学基础(二)

机器学习中的数学基础(二)2 线代2.1 矩阵2.2 矩阵的秩2.3 内积与正交2.4 特征值与特征向量2.5 SVD矩阵分解2.5.1 要解决的问题2.5.2 基变换2.5.3 特征值分解2.5.4 奇异值分解(SVD)在看西瓜书的时候有些地方的数学推导(…

使用redis快速实现session共享,springboot

1.引入依赖 <dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId> </dependency> <!-- 引入 redis 依赖 --> <dependency><groupId>org.springframework.b…

8.2 数据结构——插入排序

1、基本思想&#xff1a;每步将一个排序的对象&#xff0c;按其关键码大小插入到前面已经排好序的一组对象的适当位置上&#xff0c;直到对象全部插入为止。即边插入边排序&#xff0c;保证子序列中随时都是有序的。 2、基本操作&#xff1a; &#xff08;1&#xff09;在有序…

嗯哦哎辟 NOIP 2022 游寄

虽然上次不是假的&#xff0c;但这次是真的寄了。 Day 0 虽然是南京本地人&#xff0c;但因疫情原因&#xff0c;晚上决定去住了酒店。 看了一眼考场&#xff0c;感觉位置小得离谱。不愧是 NOI 2022 团体总分第十的“强省”江苏。 刚开始去了 409&#xff0c;发现房间里一股…

非凡社群管理之社群管理如何制定规则

1、加人规则&#xff1a;我们上篇文章里说到了&#xff0c;拉人前也是要进行一个明确定位的&#xff0c;不能什么人都拉&#xff0c;这就是我们常说的“设门槛”&#xff0c;避免占用群资源以及后期花费精力对其进行筛除。常用到的方式有这么几种&#xff1a;邀请式&#xff08…

【C++】类和对象(下)(再谈构造函数 初始化列表 explicit关键字 static成员 特性 友元 友元函数 友元类 内部类 匿名对象)

文章目录再谈构造函数初始化列表explicit关键字static成员特性友元友元函数友元类内部类匿名对象再谈构造函数 我们之前学习构造函数的时候&#xff0c;调用构造之后对象中就已经有了一个初始值&#xff0c;但不能说它是对对象像成员变量的初始化&#xff0c;构造函数体中的语…

windows10不支持Miracast无线投屏(不能进行无线投影)

电脑屏幕小看视频不爽&#xff0c;想把电脑屏幕投屏到电视上&#xff08;单独买一块高质量显示屏太贵&#xff0c;而且没有大尺寸的电视看的爽&#xff09;&#xff0c;但是windows提示不支持Miracast&#xff0c;跟着下面步骤教你解决问题。 当链接电视时出现下图提示不支持Mi…

SpringBoot 3.0 来啦!

SpringBoot 3.0 来啦&#xff01;&#xff01; 大家好&#xff0c;我 是 Ding Jiaxiong。 没赶上热乎的&#xff0c;晚了两天&#xff0c;2022年11月24日&#xff0c;SpringBoot 3.0 正式发布了&#xff01; 文章目录SpringBoot 3.0 来啦&#xff01;&#xff01;1 看看官网2…

ARM 37 个通用寄存器详解

一、简介 1、ARM 总共有 37 个寄存器&#xff0c;但是每种模式下最多只能看到 18 个寄存器&#xff0c;其他寄存器虽然名字相同&#xff0c;但是在当前模式不可见。 2、例如&#xff0c;对 r13 这个名字来说&#xff0c;在 ARM 中共有 6 个名叫 r13&#xff08;又叫 sp&#x…

SpringBoot SpringBoot 原理篇 1 自动配置 1.10 bean 的加载方式【八】

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 原理篇 文章目录SpringBootSpringBoot 原理篇1 自动配置1.10 bean 的加载方式【八】1.10.1 BeanDefinitionRegistryPostPro…

ABAP学习笔记之——第五章:内表

内表&#xff1a; 内表是可以在程序内部定义且使用的表&#xff0c;属于本地表。 与C语言比较&#xff1a; C语言的数组和内表比较&#xff1a; 内表是动态数组(Dynamic Data Object) INITIALSIZE 语句并非实际占用内存空间&#xff0c;而只是预约(RESERVE)内存空间。 创建…

Python每日一练 06

Python每日一练 06 文章目录Python每日一练 06while循环实例一、斐波那契数列前n项实例二、Leibniz公式计算圆周率while循环 循环结构表示程序重复执行某个或某些操作&#xff0c;直到某条件为假&#xff08;或为真&#xff09;时才可终止循环。 在问题求解过程中&#xff0c;…

[算法笔记]最长递增子序列和编辑距离

最长递增子序列 例如对于 a[] {2,1,5,3,6,4,8,9,7}其最长递增子序列为{1,3,4,8,9}所以长度&#xff08;或者说是结果&#xff09;为5。 对于a[0...n-1]&#xff0c;用dp[i]表示a[0...i]中以a[i]结尾的最长递增子序列长度 其状态状态方程&#xff1a; dp[i]1 // 0≤i≤…