当前位置: 首页 > 知识库问答 >
问题:

最小行乘以最大行

沈宇定
2023-03-14

我有两个矩阵,如下所示:

M<-matrix(c(1,4,1,3,1,4,2,3,1,2,1,2),3)

1    3    2    2
4    1    3    1
1    4    1    2

N<-matrix(c(1,1,2,2,3,4,-2,2,1,4,3,-1),3)

1    2   -2    4
1    3    2    3
2    4    1   -1

我想找到一个向量,它是一个矩阵1*3,它的每一个元素都是M的每一行的最小元素乘以N的对应行的最大元素(例如,向量的第一个元素是矩阵M的第一行的最小元素,即1,乘以矩阵N的第一行的最大元素,即4,因此向量的第一个元素是1*4,即4)。最后的答案是:(1*4,1*3,1*4)=(4,3,4)

为了找到这个向量(或矩阵),我写了下面的代码:

c(min(M[1,])*max(N[1,]),min(M[2,])*max(N[2,]),min(M[3,])*max(N[3,]))

但它太长了。有人能写一个更短(或更简单,或更容易)的代码吗?

共有2个答案

钱运浩
2023-03-14

解决这个问题的最直接的方法,也许也是最可读的方法是使用apply(正如@Jan已经建议的那样):apply(M,1,min)*apply(N,1,max)

但是,如果您有很多数据,则循环遍历所有数据的应用方法可能会很慢。更快的方法是使用内置的矢量化函数对所有行一起执行快速操作。
Rmax.col(m)函数返回矩阵m每行中值最高的列的索引。没有min.col(m)函数,但是您显然可以得到与使用max.col(-m)相同的结果。因此,矢量化方法是:

M_min_of_each_row=M[cbind(seq_len(nrow(M)),max.col(-M))]
N_max_of_each_row=N[cbind(seq_len(nrow(N)),max.col(N))]
answer=M*N

这对一个大矩阵来说要快多少?我们可以使用microbenchmark来测试:

using_apply=function(M,N) apply(M,1,min)*apply(N,1,max)
using_maxcol=function(M,N) M[cbind(seq_len(nrow(M)),max.col(-M))]*N[cbind(seq_len(nrow(N)),max.col(N))]
library(microbenchmark)
M=matrix(sample(1:100,40000,replace=T),ncol=4);N=matrix(sample(1:100,40000,replace=T),ncol=4)
microbenchmark(using_apply(M,N),using_maxcol(M,N))
# Unit: milliseconds
#               expr       min        lq      mean    median        uq       max neval
#  using_apply(M, N) 25.319694 28.411979 31.762766 30.829093 33.789692 71.893174   100
# using_maxcol(M, N)  1.608357  1.876968  2.117926  2.042053  2.270023  4.858531   100

# check that the results are the same:
all(using_apply(M,N)==using_maxcol(M,N))
# [1] TRUE

所以:矢量化方法大约快15倍。但是,当然,你可以认为<代码>应用方法是足够好的,而且它更简洁,而且可以说是更可读的…

黄弘盛
2023-03-14
apply(M, 1, min) * apply(N, 1, max)
 类似资料:
  • 最小二乘法是用来做函数拟合或者求函数极值的方法。在机器学习,尤其是回归模型中,经常可以看到最小二乘法的身影,这里就对我对最小二乘法的认知做一个小结。 1.最小二乘法的原理与要解决的问题 最小二乘法是由勒让德在19世纪发现的,原理的一般形式很简单,当然发现的过程是非常艰难的。形式如下式: 目标函数 = Σ(观测值-理论值) $$^2$$ 观测值就是我们的多组样本,理论值就是我们的假设拟合函数。目标函

  • 给定N个数字,范围为-100.100。 要求重新排列元素以使产品价值之和最大。此任务中的乘积和定义为a1*a2+a2*a3..an-1*an 例如,给定数字10 20 50 40 30。 1,-2,3,-4,5,-6,7,-8,9,10,11,12,13,14,15,-16 预期的最大乘积为1342。 我的算法给出了下一个重排:

  • 问题内容: 我有一张价格变动表,我需要获取初始价格和最新价格。换句话说,我想在每种产品的一行中显示min(StartDate)和max(StartDate)的价格值。 表的结构很简单: 所需的结果是 问题答案: SQLFiddle演示

  • 1 原理   给定n个带权的观察样本$(w_i,a_i,b_i)$: $w_i$表示第i个观察样本的权重; $a_i$表示第i个观察样本的特征向量; $b_i$表示第i个观察样本的标签。   每个观察样本的特征数是m。我们使用下面的带权最小二乘公式作为目标函数: minimize{x}\frac{1}{2} \sum{i=1}^n \frac{wi(a_i^T x -b_i)^2}{\sum{k=

  • 问题内容: 可以说我有一个包含许多这样的行的表: 我正在做一个简单的查询,像这样: 运行此查询后,我得到如下结果: 非常简单 :) 我现在需要做的是选择计数大于10的具有最小和最大利润的行(这是一个参数) 我能够通过此获得最小值: 我正在考虑使用ORDER BY DESC进行上述查询,但这不是最佳解决方案。 我需要做的是: 选择2行:按范围分组时,第一行最少,第二行最大AVG利润。 编辑: 如果我

  • 问题内容: 我被分配编写一个程序,该程序读取一系列整数输入并打印-输入的最小和最大-以及偶数和奇数输入的数量 我想出了第一部分,但对如何使程序显示最大和最小感到困惑。到目前为止,这是我的代码。我怎样才能显示最小的输入呢? 问题答案: 最简单的解决方案是使用诸如和