草庐IT

关于矩阵:比较两个矩阵R之间的信息

codeneng 2023-03-28 原文

compare the information between two matrices R

我有两个矩阵,一个是通过删除一些行从另一个生成的。例如:

1
2
m = matrix(1:18, 6, 3)
m1 = m[c(-1, -3, -6),]

假设我不知道 m 中的哪些行被删除来创建 m1,我应该如何通过比较两个矩阵来找到它?我想要的结果是这样的:

1
1, 3, 6

我正在处理的实际矩阵非常大。我想知道是否有任何有效的方法来进行。


这里有一些方法:

1) 如果我们可以假设 m 中没有重复的行——问题示例中就是这种情况——那么:

1
2
which(tail(!duplicated(rbind(m1, m)), nrow(m)))
## [1] 1 3 6

2) 转置 mm1 给出 tmtm1 因为在列上工作比在行上工作更有效。

定义 match_indexes(i),它返回一个向量 r,使得 m[r, ] 中的每一行都匹配 m1[i, ]

将其应用于 1:n1 中的每个 i 并从 1:n 中删除结果。

1
2
3
4
5
6
n <- nrow(m); n1 <- nrow(m1)
tm <- t(m); tm1 <- t(m1)

match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1)
setdiff(1:n, unlist(lapply(1:n1, match_indexes)))
## [1] 1 3 6

3) 计算每个矩阵的交互向量,然后使用 setdiff 最后使用 match 得到索引:

1
2
3
4
i <- interaction(as.data.frame(m))
i1 <- interaction(as.data.frame(m1))
match(setdiff(i, i1), i)
## [1] 1 3 6

已添加如果 m 中可能有重复项,则 (1) 和 (3) 将仅返回 m 中的任何多次出现的行中的第一个,而不是 m1 中的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
m <- matrix(1:18, 6, 3)
m1 <- m[c(2, 4, 5),]
m <- rbind(m, m[1:2, ])
# 1
which(tail(!duplicated(rbind(m1, m)), nrow(m)))
## 1 3 6

# 2
n <- nrow(m); n1 <- nrow(m1)
tm <- t(m); tm1 <- t(m1)
match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1)
setdiff(1:n, unlist(lapply(1:n1, match_indexes)))
## 1 3 6 7

# 3
i <- interaction(as.data.frame(m))
i1 <- interaction(as.data.frame(m1))
match(setdiff(i, i1), i)
## 1 3 6

  • 我更喜欢第一个。它也更快。请参阅我的答案中的基准。
  • 第一个很棒。但不幸的是,我的 m 矩阵本身有重复的行。不过,我喜欢你在这里提出的新颖方法。谢谢!
  • 其实我们可以稍微放宽一下条件。如果m1中有重复的行,m中的重复行也是可以的。如果 m 中有重复的行不在 m1 中,则只有每个多重出现的行中的第一个将包含在输出向量中。这够好吗?


一种可能的方式是将每一行表示为一个字符串:

1
2
3
4
x1 <- apply(m, 1, paste0, collapse = ';')
x2 <- apply(m1, 1, paste0, collapse = ';')
which(!x1 %in% x2)
# [1] 1 3 6

使用我的解决方案和 G. Grothendieck 的解决方案对大型矩阵进行一些基准测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
set.seed(123)
m <- matrix(rnorm(20000 * 5000), nrow = 20000)
m1 <- m[-sample.int(20000, 1000), ]

system.time({
    which(tail(!duplicated(rbind(m1, m)), nrow(m)))
})
#    user  system elapsed
# 339.888   2.368 342.204
system.time({
    x1 <- apply(m, 1, paste0, collapse = ';')
    x2 <- apply(m1, 1, paste0, collapse = ';')
    which(!x1 %in% x2)
})
#    user  system elapsed
# 395.428   0.568 395.955

system({
    n <- nrow(m); n1 <- nrow(m1)
    tm <- t(m); tm1 <- t(m1)

    match_indexes <- function(i) which(colSums(tm1[, i] == tm) == n1)
    setdiff(1:n, unlist(lapply(1:n1, match_indexes)))
})
# > 15 min, not finish


system({
    i <- interaction(as.data.frame(m))
    i1 <- interaction(as.data.frame(m1))
    match(setdiff(i, i1), i)
})
# run out of memory. My 32G RAM machine crashed.

  • 非常感谢你!但我的矩阵 m 实际上是一个包含 14290 行和 4413 个术语的文档术语矩阵。这种方法能处理这么大的矩阵吗?
  • @user7453767,这个在那个大矩阵上非常慢。我做了一个测试示例并在几分钟前运行它。它还没有完成。
  • 这很有帮助!谢谢@mt1022


我们也可以使用 do.call

1
2
which(!do.call(paste, as.data.frame(m)) %in% do.call(paste, as.data.frame(m1)))
#[1] 1 3 6

有关关于矩阵:比较两个矩阵R之间的信息的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  4. ruby-on-rails - Rails 应用程序之间的通信 - 2

    我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此

  5. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  6. ruby - #之间? Cooper 的 *Beginning Ruby* 中的错误或异常 - 2

    在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee

  7. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  8. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  9. 旋转矩阵的几何意义 - 2

    点向量坐标矩阵的几何意义介绍旋转矩阵的几何含义之前,先介绍一下点向量坐标矩阵的几何含义点:在一维空间下就是一个标量,如同一条直线上,以任意某一个位置为0点,以一定的尺度间隔为1,2,3...,相反方向为-1,-2,-3...;如此就形成了一维坐标系,这时候任何一个点都可以用一个数值表示,如点p1=5,即即从原点出发沿着x轴正方向移动5个尺度;点p2=-3,负方向移动3个尺度;     在一维坐标系上过原点做垂直于一维坐标系的直线,则形成了二维坐标系,此时描述一个点需要两个数值来表示点p3=(3,2),即从原点出发沿着x轴正方向移动3个尺度,在此基础上沿着y轴正方向移动两个尺度的位置就是点p3。

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐