合并相同数据的行_R语言笔记(六):数据框重塑(reshape2)

db070b1d5dfa0642ede52be35b4ee627.png

数据处理主要内容包括:

  • 1. 特殊值处理
    • 1.1 缺失值
    • 1.2 离群值
    • 1.3 日期
  • 2. 数据转换(base vs. dplyr)
    • 2.1 筛选(subset vs. filter/select/rename)
    • 2.2 排序(order vs. arrange)
    • 2.3 转换(transform vs. mutate/transmute)
    • 2.4 分组与概括(group_by/summarise)
  • 3. 数据框重塑(base vs. dplyr)
    • 3.1 数据框的合并(rbind/cbind vs. bind_rows/bind_cols)
    • 3.2 数据框的关联(merge vs. *_ join)
    • 3.3 数据框的长宽转换(reshape2 包)

本文我们学习数据框重塑的有关内容。前文链接:

Sub-woo:R语言笔记(四):数据处理(上)​zhuanlan.zhihu.com
865e1921db6eafaf7012d6063ca18330.png
Sub-woo:R语言笔记(四):数据处理(中)​zhuanlan.zhihu.com
4f127d6dc1540aa059c06d546fbe6847.png

有出错或补充的地方请大神们不吝赐教,作者会持续更新!


3. 数据框重塑

这篇文章我们主要介绍基本包和 dplyr 包中用于数据框操作的函数,包括多个数据框的合并、关联以及长宽数据框的转换。

字符串的拼接可以通过 paste() 函数实现,而多个数据框也同样可以通过函数合成为一个数据框。与字符串不同的是,多个数据框的合成方式有两种,一种是合并(父母之命,媒妁之言),另一种是关联(相信缘分,因为爱情)。以下是段子,没兴趣的小伙伴可以跳过。

【段子:如何理解合并是“父母之命,媒妁之言”?这几个要合并的数据框往往没有相同的行或者列,我们只想硬生生地把它们拼成一个整体而已,或者说它们在一起不是因为相互有什么相同点,只是因为我们(父母)想[doge]。】

【段子:那又如何理解关联是“因为爱情”呢?需要关联的数据框往往具有某些相同的行或者列,比如有两份数据框,一份是小明和小红的数学成绩,另一份是小明和小红的英语成绩,很显然两份数据框都有相同的人名,因此我们就可以将二者关联,形成一份体现小明和小红数学、英语成绩的成绩单。这些相同的行或列就好比缘分和爱情,正因为有了共同点,数据框们才能更紧密地结合,更幸福地生活=。=】

3.1 数据框的合并(rbind/cbind vs. bind_rows/bind_cols)

  • base 包(rbind/cbind)

base 包提供的实现合并的函数有两个,分别是:

rbind()
# 纵向合并
cbind()
# 横向合并

【注】rbind() 要求数据框的列数相同,同时列名也要一致;cbind() 要求数据框的行数相同。举几个例子:

set1 <- data.frame(a = 1: 4, b = LETTERS[1: 4])
set2 <- data.frame(a = 0, b = c("I", "love", "u"), c = c(5, 2, 0))set1 # 4×2 的数据框
#   a b
# 1 1 A
# 2 2 B
# 3 3 C
# 4 4 D
set2 # 3×3 的数据框
#   a    b c
# 1 0    I 5
# 2 0 love 2
# 3 0    u 0# rbind(set1, set2) 列数不相同会报错
# cbind(set1, set2) 行数不相同会报错rbind(set1, set2[, 1:3]) # 只取 set2 的前两列,使得列数与 set1 相同
#   a    b
# 1 1    A
# 2 2    B
# 3 3    C
# 4 4    D
# 5 0    I
# 6 0 love
# 7 0    u
cbind(set1[1: 3, ], set2) # 只取 set1 的前三行,使得行数与 set2 相同a b a    b c
1 1 A 0    I 5
2 2 B 0 love 2
3 3 C 0    u 0
# 合并出现了两个 a 列

【注】使用 cbind() 合并数据框后,可能出现列名相同的情况,某种程度上算是 cbind() 的缺陷,因此作者也更倾向于使用 dplyr 包提供的合并函数。

  • dplyr 包(bind_rows/bind_cols)

dplyr 包提供的数据框合并函数也有两个,分别是:

bind_rows()
# 纵向拼接
bind_cols()
# 横向拼接

【注】bind_rows() 根据列名对数据框进行合并,同一列名的列进行合并,不同列名的列会自动进行补齐(默认使用 NA 补齐),最好保证相同列名的数据类型是一致的;bind_cols() 要求数据框的行数相同,若有相同列名,则会自动进行修改区分。接下来举例说明:

library(dplyr)
one <- data.frame(a = c("I", "love", "U"), b = 0, c = c(5, 2, 0), stringsAsFactors = F)
two <- data.frame(a = c("13", "14"), d = LETTERS[1: 2], stringsAsFactors = F)
# 保证 two 的 a 列数据类型与 one 的 a 列一致,均为字符型one # 3×3 数据框
#      a b c
# 1    I 0 5
# 2 love 0 2
# 3    U 0 0
two # 3×3 数据框
#    a d
# 1 13 A
# 2 14 Bbind_rows(one, two)
#      a  b  c    d
# 1    I  0  5 <NA>
# 2 love  0  2 <NA>
# 3    U  0  0 <NA>
# 4   13 NA NA    A
# 5   14 NA NA    B
# 可以看到,bind_rows() 对相同列名的数据进行了合并,列名不同的列则自动使用 NA 进行了补齐。# bind_cols(one, two) 报错,两个数据框行数不一致
bind_cols(one[1:2, ], two)
#      a b c a1 d
# 1    I 0 5 13 A
# 2 love 0 2 14 B
# 自动对相同的列名进行了修改

3.2 数据框的关联(merge vs. *_ join)

  • base 包(merge)

基本包提供的数据框关联函数为 merge() ,能够根据两个数据框相关的列进行关联,附上参考资料:R语言使用merge函数匹配数据(vlookup,join),语法如下:

merge(x, y, by = intersect(names(x), names(y)),by.x = 列名1, by.y = 列名2, all = FALSE, all.x = all, all.y = all,sort = TRUE, suffixes = c(".x",".y"), no.dups = TRUE,incomparables = NULL, ...)
x,y:要合并的两个数据集
by:用于连接两个数据集的列,intersect(a,b)值向量a,b的交集,names(x)指提取数据集x的列名
by:intersect(names(x), names(y)) 是获取数据集x,y的列名后,提取其公共列名,作为两个数据集的连接列, 当有多个公共列时,需用下标指出公共列,如names(x)[1],指定x数据集的第1列作为公共列。也可以直接写为 by = "公共列名" ,前提是两个数据集中都有该列名,并且大小写完全一致,R语言区分大小写
by.x,by.y:指定依据哪些列关联数据框,默认值为相同列名的列
all,all.x,all.y:指定x和y的行是否应该全在输出文件
sort:by指定的列(即公共列)是否要排序
suffixes:指定除by外相同列名的后缀;如设置 suffixes = c(".xx", ".yy"),两个数据框都有列名 grade,关联后就会被区分为 grade.xx 和 grade.yy
incomparables:指定by中哪些单元不进行关联

其中,常用的参数有 by(根据相同列名的列进行关联);by.x/by.y(可以分别指定两个数据框的列进行关联);all/all.x/all.y(逻辑变量,控制返回 x 和 y 所有/仅 x 数据框/仅 y 数据框的行);sort(逻辑变量,根据关联的列进行排序)。

下面举例说明:

grade1 <- data.frame(number = c(2, 3, 1), Names = c("小明", "小红", "小李"), math = c(90, 80, 100))
grade2 <- data.frame(number = c(3, 1, 4), NAMES = c("小红", "小李", "小张"), english = c(100, 90, 80))
grade3 <- data
# 两个数据框定义了学号、姓名和成绩
grade1
#   number Names math
# 1      2  小明   90
# 2      3  小红   80
# 3      1  小李  100
grade2
#   number NAMES english
# 1      3  小红     100
# 2      1  小李      90
# 3      4  小张      80merge(grade1, grade2)
#   number Names math NAMES english
# 1      1  小李  100  小李      90
# 2      3  小红   80  小红     100

默认条件下,根据两个数据框相同列名的列(学号)进行关联,由于 Names 和 NAMES 大小写不一致,因此不会关联该列;只保留两个数据框的交集部分(共有的),省略了小明和小张的数据。我们可以通过 by.x/by.y 分别指定需要关联的列名:

merge(grade1, grade2, by.x = c("number", "Names"), by.y = c("number", "NAMES"))
#   number Names math english
# 1      1  小李  100      90
# 2      3  小红   80     100

这样就实现了通过学号和姓名进行数据框的关联。接下来我们通过 all/all.x/all.y 指定保留我们想要的行:

merge(grade1, grade2, by.x = c("number", "Names"), by.y = c("number", "NAMES"),all = T) # 返回并集(保留所有行)
#   number Names math english
# 1      1  小李  100      90
# 2      2  小明   90      NA
# 3      3  小红   80     100
# 4      4  小张   NA      80
# 使用 NA 填补了缺失值merge(grade1, grade2, by.x = c("number", "Names"), by.y = c("number", "NAMES"),all.x = T) # 仅保留 x 数据框的所有行
#   number Names math english
# 1      1  小李  100      90
# 2      2  小明   90      NA
# 3      3  小红   80     100
# 保留了 x 的所有行,因此小明的成绩被留下了merge(grade1, grade2, by.x = c("number", "Names"), by.y = c("number", "NAMES"),all.y = T) # 仅保留 y 数据框的所有行
# 大家猜猜看结果

最后我们通过 sort 对关联的变量进行排序,默认 sort = T,将 by 中的第一个变量作为第一依据,第二个变量作为第二依据,以此类推进行排序。注意观察下述代码与之前的差异:

merge(grade1, grade2, by.x = c("Names", "number"), by.y = c("NAMES", "number"),all = T)
#   Names number math english
# 1  小红      3   80     100
# 2  小李      1  100      90
# 3  小明      2   90      NA
# 4  小张      4   NA      80

可以看到,将 by 中 names 移到首位后,排序方式也发生了变化——根据姓名升序排列。

  • dplyr 包(* _ join)

dplyr 包提供的关联数据框的函数包括以下几种:

inner_join(x, y, by = , copy = F, suffix = c(), ...)
# 返回交集
left_join(x, y, by = , copy = F, suffix = c(), ...)
# 返回 x 所有的行数据与交集,类似 merge 中 all.x = T
right_join(x, y, by = , copy = F, suffix = c(), ...)
# 返回 y 所有的行数据与交集,类似 all.y = T
full_join(x, y, by = , copy = F, suffix = c(), ...)
# 返回并集(所有数据),类似 all = T
semi_join(x, y, by = , copy = F)
# 保留 x 所有的列名,返回行的交集
anti_join(x, y, by = , copy = F)
# 保留 x 所有的列名,返回行的 x 与 !y 的交集(从 x 中剔除与 y 匹配的行)

【注】by 可以赋值行名,也可以通过 by = c("列名1" = "列名2", ...) 进行指定;suffix 的功能与 merge 中的 suffixes 类似。下面介绍一下 semi_ join() 与 anti_ join() 的效果:

grade1 <- data.frame(number = c(2, 3, 1), Names = c("小明", "小红", "小李"), math = c(90, 80, 100))
grade2 <- data.frame(number = c(3, 1, 4), NAMES = c("小红", "小李", "小张"), english = c(100, 90, 80))
# 继续使用上面的数据框semi_join(grade1, grade2)
# Joining, by = "number"
#   number Names math
# 1      3  小红   80
# 2      1  小李  100inner_join(grade1, grade2) # 对比交集
#   number Names math NAMES english
# 1      3  小红   80  小红     100
# 2      1  小李  100  小李      90

观察到 semi_ join 保持了 grade1 的表格形式,数据则是 grade1 与 grade2 的交集,因此也可以理解为将数据的交集填入形如 grade1 的表格中。anti_ join 也是类似的效果:

anti_join(grade1, grade2)
# Joining, by = "number"
#   number Names math
# 1      2  小明   90

返回的数据是 grade1 中除去了与 grade2 共有的部分(即 x & !y,或者是

),填入形如 grade1 的表格中。

3.3 数据框的长宽转换(reshape2 包)

  • 什么是长数据/宽数据

首先聊聊什么是长数据和宽数据。作者是这样理解的,长数据的格式可以较为笼统地认为只有三列,一列用于存储索引值,一列用于存储 variable,最后一列用于存储 value【类似于映射,第一列对应坐标,第二列对应映射方式(函数),第三列对应函数值(value)】。只是当索引值以多个维度存在的时候,就会出现四列甚至更多,举个例子,将日期作为索引值,最高温/最低温作为 variable,温度值作为 value 存储时,数据框就可能是如下类型:

5e1e61835201b2e1d41e5c872c497338.png
2020/1/6 缺少最低温,但在长数据中不会体现出来

当索引值以更高维度表现时,如将日期格式的年/月/日分开书写,就会是下面的样子:

85c502c7a726920909b7fa857222ca39.png

那宽数据又是什么样的呢?类似于长数据,可以笼统地认为宽数据只有两行,第一行用于存储变量名,第二行用于存储每个变量名对应的 value(列向量的形式存在),我们平时观察的表格往往就是宽数据的形式。同样使用温度的数据,其宽数据的表现形式就像下面的表格:

a75620612ee2ab7a449b3576fca62c15.png
在宽数据格式下,缺失值会被体现出来

是不是看起来亲切很多?

两种格式各有优点,多数时候长数据的存储占用空间比宽数据小(从缺失值可以大概领会一点),长数据的增删读取比宽数据效率更高;宽数据在形式上更清晰,而且由于其 value 是以列向量的形式存在,也能更好地适应 R 语言大多函数的调用

  • 长宽数据转换的代码实现

基本包中的 reshape/stack/unstack 函数可以实现长宽数据的转换,但使用起来比较麻烦,现在很少有人使用,目前使用比较多的是 tidyr 包中的 gather/spread 函数和 reshape2 包中的 melt/dcast 函数。本篇文章只介绍 reshape2 包中转换数据框长宽数据的函数(只会这个...):

melt(data, id.vars, measure.vars,variable.name = "variable", ..., na.rm = FALSE, value.name = "value",factorsAsStrings = TRUE)
# 将宽数据转换为长数据dcast(data, formula, fun.aggregate = NULL, ..., margins = NULL,subset = NULL, fill = NULL, drop = TRUE,value.var = guess_value(data))
# 将长数据转换为宽数据

在 melt() 中,id.vars(亦作 id ) 对应长数据的第二列(映射方式/函数);measure.vars(亦作 measure ) 对应长数据的第三列(value/函数值);variable.name 指定第二列的列名;value.name 指定第三列的列名;na.rm = F 不移除缺失值,为 T 则移除缺失值;factorsAsStrings = T 将因子转换为字符串,为 F 则不转换。

在 dcast() 中,formula 的形式为 x_variable + x_2 ~ y_variable + y_2 ~ z_variable ~ ...,左端对应宽数据中的索引值,右端对应宽数据中的 variable 和 value;fun.aggregate 用于指定函数,若对应某个索引值的 value 个数多于一个,则需要通过 fun.aggregate 函数处理这些 values,使之聚合为一个 value(每个 x 有且仅有一个 y 值与之对应,才能成为映射),如函数 sum/mean/sd 等;fill 指定填补缺失值,默认用 fun.aggregate 函数对空向量返回的值填补。

下面用 R 自带的 airquality 数据集举例说明:

library(reshape2)
dat <- airquality
head(dat) # 显示前六条数据
#   Ozone Solar.R Wind Temp Month Day
# 1    41     190  7.4   67     5   1
# 2    36     118  8.0   72     5   2
# 3    12     149 12.6   74     5   3
# 4    18     313 11.5   62     5   4
# 5    NA      NA 14.3   56     5   5
# 6    28      NA 14.9   66     5   6

可以看到,airquality 是宽数据的形式,接下来我们尝试将其转换为长数据。

dat_long <- melt(dat, id.vars = c("Month", "Day"), measure.vars = c("Ozone", "Solar.R"), na.rm = T,variable.name = "Vars", value.name = "Vals")
head(dat_long)
#   Month Day  Vars Vals
# 1     5   1 Ozone   41
# 2     5   2 Ozone   36
# 3     5   3 Ozone   12
# 4     5   4 Ozone   18
# 6     5   6 Ozone   28
# 7     5   7 Ozone   23

【注】代码中设置了 na.rm = T 因此缺失值会直接被移除,如 5 月 5 日的 Ozone 没有观测值,5 月 6 日的 Solar.R 没有观测值,因此这里不会显示 5 月 5 日的 Ozone。

以 Month 和 Day 构建二维的索引值,Ozone 和 Solar.R 作为 variable,两个变量对应的数据作为 value 填入。但前六条记录没有显示出 Solar.R 是为什么呢?因为 R 将 Ozone 的值存储完毕以后才进行 Solar.R 的存储,如下图所示:

f91ae7dbc786ca3ef7114c10c7523057.png
从第 154 条数据开始记录 Solar.R 的 value

【注】代码的运行结果可以看到 5 月 6 日的 Solar.R 没有观测值,因此在长数据中会被移除,但 5 月 6 日的 Ozone 有观测值,在长数据中没有被移除,与宽数据格式中缺失值的移除有所差异(宽数据格式中,缺失值会被按行移除,意味着 5 月 6 日的所有数据都会被 remove)

下面我们试试将长数据转换为宽数据:

dat_wide <- dcast(dat_long, Month + Day ~ Vars)
# 注意这里使用 Vars 而不是 Ozone 和 Solar.R
# 因为在 dat_long 中只有 Vars
head(dat_wide)
#   Month Day Ozone Solar.R
# 1     5   1    41     190
# 2     5   2    36     118
# 3     5   3    12     149
# 4     5   4    18     313
# 5     5   6    28      NA
# 6     5   7    23     299

这里没有 5 月 5 日的数据是因为在将 dat 转换为 dat_long 的过程中,分别删除了 Ozone 和 Solar. R 的缺失值,而 5 月 5 日恰巧同时缺失这两个数据,因此后续将 dat_long 转换为 dat_wide 后,dat_wide 中就不存在 5 月 5 日的数据了。我们尝试将 na.rm 设置为 F 看看结果有什么不同:

dat <- airquality
dat_long <- melt(dat, id = c("Month", "Day"), measure = c("Ozone", "Solar.R"))
head(dat_long)
#   Month Day variable value
# 1     5   1    Ozone    41
# 2     5   2    Ozone    36
# 3     5   3    Ozone    12
# 4     5   4    Ozone    18
# 5     5   5    Ozone    NA
# 6     5   6    Ozone    28dat_wide <- dcast(dat_long, Month + Day ~ variable)
head(dat_wide)
#   Month Day Ozone Solar.R
# 1     5   1    41     190
# 2     5   2    36     118
# 3     5   3    12     149
# 4     5   4    18     313
# 5     5   5    NA      NA
# 6     5   6    28      NA

如结果所示,5 月 5 日的数据会一直被保留下来。

再来看一个更复杂的例子:

set.seed(100)
grades <- data.frame(Month = rep(c(7,8), each = 5), Day = rep(seq(1, 31, by = 7), times = 2), Tom = sample(85:100, 10), Amy = sample(90:100, 10))
# 生成一个关于 Tom 和 Amy 在七、八月份的周测成绩

成绩单如下表所示:

64b4cc846444551f9cc76c6e7930a8ef.png

接着我们想要将其存储在数据库中,将其转换为长数据:

grades_long <- melt(grades, id = c("Month", "Day"), measure = c("Tom", "Amy"))

结果如下表所示:

ef5f76a3aff20d90ac23510501897563.png

到了开家长会的时候,我们想要计算 Tom 和 Amy 的每月平均成绩,可以通过如下代码实现:

grades_wide <- dcast(grades_long, Month ~ variable, fun.aggregate = mean)
grades_wide
#   Month  Tom  Amy
# 1     7 91.0 95.8
# 2     8 96.2 94.4

由于每一个 Month 的值都对应 7 个 grades,因此我们使用 mean 求平均值,这样通过 dcast() 中的 fun.aggregate 参数就可以非常便捷地获得我们想要的数据啦~

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

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

相关文章

启动linux_使用 UEFI 双启动 Windows 和 Linux | Linux 中国

这是一份在同一台机器上设置 Linux 和 Windows 双重启动的速成解释&#xff0c;使用统一可扩展固件接口&#xff08;UEFI&#xff09;。来源&#xff1a;https://linux.cn/article-12891-1.html作者&#xff1a;Alan Formy-duval译者&#xff1a;郑&#xff08;本文字数&#x…

mysql+odbc+ado_MFC ado+mysql+odbc技术分享

第一步&#xff1a;建立数据库假设有一个sql文件mysql>use dbname; //创建一个数据库名为dbname的数据库(空数据库)mysql>set names utf8; //编码&#xff0c;mysql>source D:/dbname.sql; //导入一个数据库源文件创建数据库内容我做…

js 用下标获取map值_javascript怎么获取map的值?

Map对象保存键/值对&#xff0c;是键/值对的集合。任何值(对象或者原始值) 都可以作为一个键或一个值。Object结构提供了“字符串—值”的对应&#xff0c;Map结构提供了“值—值”的对应。JavaScript获取map值示例&#xff1a;map对象如下&#xff1a;var mapObject {id1001:…

python attention机制_从零开始学Python自然语言处理(26)—— 强大的Attention机制...

前文传送门&#xff1a;在上一次面试失利后&#xff0c;我回来仔细研究了一下Attention机制&#xff0c;研究完我不禁感悟&#xff0c;这机制真的厉害啊&#xff01;因为我之前面试被问到的Encoder - Decoder框架中有个瓶颈是编码的结果以固定长度的中间向量表示&#xff0c;这…

[机器人-2]:开源MIT Min cheetah机械狗设计(二):机械结构设计

目录 1、四肢朝向的选择 2、电机布局形式的选择 3、电机的选型及测试&#xff08;非常重要&#xff09; 4、结构优化 5、尺寸效应 6、其他 1、四肢朝向的选择 机械狗的结构设计&#xff0c;第一个摆在我们面前的就说四肢的朝向问题&#xff0c;如下图&#xff0c;我们是…

mysql用户权限表join_MyBatis映射利用mysql left join 解决N+1查询问题

1.权限是几乎每个系统都需要的2.一般在用户请求某个url的时候&#xff0c;都需要验证用户是否拥有该url的访问权限3.最简单的权限系统需要 用户表&#xff0c;角色表&#xff0c;用户角色表&#xff0c;权限表&#xff0c;角色权限表# Host: 127.0.0.1 (Version: 5.6.22)# Date…

python 爬取贝壳网小区名称_如何使用 python 爬取全国小区名称

前言笔者在做一个 NLPNLPNLP 项目时&#xff0c;需要识别小区名&#xff0c;因此想要查询网上是否有相关的数据集。经过一番搜索后一无所获…从而决定自己来爬取这份数据。由于爬取网站的内容信息之后可能会发生变更&#xff0c;因此此处给出具体的爬虫思路&#xff0c;便于应对…

python获取手机通知栏消息_Python编写简单的通知栏脚本启动工具

随着自己编写的脚本与安装的工具越来越多,电脑的桌面和文件夹也越来越乱了。就在前几天因为一个不小心,我把自己的一个项目给删了,所以决定将电脑整理一下。不过这一整理我很多脚本和工具的位置我就忘记了,所以决定写个小工具来快速启动一些常用的脚本或工具这里选择Python是因…

java 发送邮件昵称_利用JavaMail发送QQ邮件

一、RFC882文档简单说明RFC882文档规定了如何编写一封简单的邮件(纯文本邮件)&#xff0c;一封简单的邮件包含邮件头和邮件体两个部分&#xff0c;邮件头和邮件体之间使用空行分隔。邮件头包含的内容有&#xff1a;from字段   --用于指明发件人to字段    --用于指明收件…

java 访问控制权限_Java访问控制权限有哪些?区别是什么?

原标题&#xff1a;Java访问控制权限有哪些&#xff1f;区别是什么?Java中的类和方法等都是有访问控制权限的&#xff0c;用来控制方法、类、属性等的生效范围&#xff0c;Java有四种访问控制权限&#xff0c;其中比较常用的就是public和private&#xff0c;今天华清远见Java学…

java 规格overview_《Java數據結構和算法》- OverView

Q: 不同數據結構的優缺點&#xff1f;數據結構優點缺點數組(Array)快速訪問&#xff0c;如果知道下標&#xff0c;就可以非常快地存取查找慢&#xff0c; 插入或刪除慢&#xff0c; 大小固定有序數組(OrderedArray)比無序的數組查找快插入或刪除慢&#xff0c;大小固定棧(Stack…

mysql 集群怎么卸载节点_Greenplum移除节点

基于某某原因&#xff0c;我们的Greenplum需要卸载一个节点(测试环境的Greenplum集群)&#xff0c;由于该集群使用了很久&#xff0c;里面有许多开发所需要的数据&#xff0c;所以在卸掉一个节点后&#xff0c;还要保证数据不会丢失。当然&#xff0c;期间也遇到了点问题&#…

python中不论类的名字是什么歌_Python自动猜歌名,还愁排名上不去嘛?

前言相传&#xff0c;就在前几日&#xff0c;在网上闲逛时&#xff0c;刷到了一个猜歌的小程序。这个小程序通过播放歌曲部分片段&#xff0c;然后让用户来猜它的歌名&#xff0c;大概是这样的&#xff1a;作为一个脑热的听歌爱好者&#xff0c;于是他越陷越深&#xff0c;越刷…

trace java_使用java动态字节码技术简单实现arthas的trace功能。

参考资料用过[Arthas]的都知道&#xff0c;Arthas是alibaba开源的一个非常强大的Java诊断工具。不管是线上还是线下&#xff0c;我们都可以用Arthas分析程序的线程状态、查看jvm的实时运行状态、打印方法的出入参和返回类型、收集方法中每个代码块耗时&#xff0c;甚至可以监控…

打印狗的健康值Java_嵌入式狗的JAVA之路 HTML 补课

学了JAVA WEB应用&#xff0c;补充一下HTML的标签&#xff0c;常用的&#xff0c;不然页面都画不出来了~~test 标题&#xff0c;h1h2h3 3个字号test 段落link 链接 使用 Target 属性&#xff0c;你可以定义被链接的文档在何处显示。下面的这行会在新窗口打开文档&#xff1a;Vi…

python 角度传感器模拟_python树莓派红外反射传感器

本文实例为大家分享了python树莓派红外反射传感器的程序&#xff0c;供大家参考&#xff0c;具体内容如下1、工具rpi3&#xff0c;微雪ARPI600&#xff0c;Infrared Reflective Sensor2、基本原理Infrared Reflective Sensor 输出数字和模拟信号模拟信号通过ARPI600上的AD转换芯…

java构造方法赋值内存图_java 面向对象(九):类的结构:构造器(一)简介;属性赋值顺序;JavaBean的概念...

1.构造器(或构造方法)&#xff1a;Constructor构造器的作用&#xff1a;* 1.创建对象* 2.初始化对象的信息2.使用说明&#xff1a;* 1.如果没显式的定义类的构造器的话&#xff0c;则系统默认提供一个空参的构造器* 2.定义构造器的格式&#xff1a;权限修饰符 类名(形参列表){}…

java 集合modcount_源码|jdk源码之LinkedList与modCount字段

链表是对上一篇博文所说的顺序表的一种实现。与ArrayList思路截然不同&#xff0c;链表的实现思路是&#xff1a;不同元素实际上是存储在离散的内存空间中的。每一个元素都有一个指针指向下一个元素&#xff0c;这样整个离散的空间就被“串”成了一个有顺序的表。从链表的概念来…

idea 新建ssm java ee_IDEA搭建SSM项目实现增删改查

首先打开IDEA&#xff0c;File—>New—>Project创建项目选择左侧导航栏里的Maven&#xff0c;勾上勾&#xff0c;选择webapp按如下图进行填写创建完成后进入项目&#xff0c;右下角弹出的提示点击右边的Enable Auto-Import&#xff0c;自动配置连接数据库&#xff0c;我用…

php mail centos_centos怎么发送邮件

一、安装sendmail与mail1、安装sendmail&#xff1a;1) centos下可以安装命令&#xff1a;yum -y install sendmail2) 安装完后启动sendmail命令&#xff1a;service sendmail start2、安装mail安装命令&#xff1a;yum install -y mailx二、发送邮件1、通过文件内容发送发送命…