【问题标题】:How to customize outer and Vectorize functions?如何自定义外部和矢量化功能?
【发布时间】:2014-03-25 13:21:43
【问题描述】:

一个月前我问过一个类似的问题。请参阅 Count the occurrences of unequal numbers from a data frame

我使用outerVectorize 函数解决了这个问题。我的解决方案如下:

dist_mat<- outer(1:nrow(df),1:nrow(df), 
                FUN = Vectorize( function(i,j) sum(df[i,]!=df[j,]))) 

这很完美,但现在我有一个巨大的矩阵,超出了我的内存大小。

在我得到dist_mat 之后,对于每一行,我计算小于或等于两个的列数,而我现在不能这样做。所以,我想知道是否可以结合外部函数中的计数操作来避免内存问题。我的结果只是一个向量。

提前谢谢你!

【问题讨论】:

  • 罗兰在其他问题的回答是否也有记忆问题? [在进一步思考后编辑我的评论:它可能确实如此,因为它只是将操作减少了不到一半,但又增加了两列。]这将是解决内存问题的一种方法;如果是这样,矢量化操作可能会以某种方式获得所需的计数。

标签: r matrix distance apply


【解决方案1】:

虽然这并不能严格回答您的问题,但您可能应该避免使用outer 并使用类似:

tot.rows <- nrow(df)
res <- numeric(tot.rows)
for(i in 1:tot.rows) 
  for(j in 1:tot.rows) 
    res[[i]] <- res[[i]] + (sum(df[i,] != df[j,]) <= 2)

outer 将从一开始就预先分配i * j 矩阵,因此在使用外部时您将很难解决问题。如果您的结果确实是一个与数据框长度相同的向量,那么您不需要 outer 在您的应用程序中生成维度矩阵 nrow(df) * nrow(df)

上述算法将运行与outer 相同数量的计算,但为每一行重复使用相同的内存空间,因为您只关心最终计数,因此它应该适合内存。 它的速度也应该与外层相当(这是我测试它的玩具示例)。只要您确实需要对每个值进行计算,并且有足够的内存来处理像 outer 这样的完全扩展,向量化操作就很棒,但它们不一定是所有问题的答案。

正如其他人在上一个答案中指出的那样,您可以修改代码,以便您不计算矩阵的对角线或其中一个三角形,因为您的距离计算是对称的,这应该可以将计算时间大致减半。

【讨论】:

  • 在进行矢量化之前我已经尝试过这个。我没有内存问题,但它运行了几个小时。可能好几天(我在 6 小时左右后停止了它)。
  • @Chris,outer 版本的运行速度应该一样慢。您是否比较了这两种方法在小到足以放入内存的数据子集上的性能?此外,您似乎真的想将计算限制在当时严格必要的计算范围内。您的数据中有重复项吗?你的数据是什么(数字、因子、字符)?
  • 你是对的,外部也很慢。我有一个因子数据类型。我现在正试图找到一种方法来减少我的数据。
  • outer 如果你给它一个真正矢量化的函数而不是使用隐藏的mapply 循环(通过Vectorize),它会很快。
【解决方案2】:

如果你有一个矩阵 DF 那么

apply(DF, 2, function(y) sum(colSums(DF==y) < 2))

可能有用吗? DF==y 将每一列与applycolSums 中的目标列进行比较,然后找出该列对中有多少行是相等的,我们将其与 2 进行比较(目标列总是与自身进行比较作为 DF==y 的一部分,因此我已将其考虑在内 - 您可能需要考虑这一点,具体取决于您的“2”阈值是否包括自我比较)。然后最后的sum 统计满足

假设您不需要中间距离矩阵,它完全重构了代码。

【讨论】:

  • 您的数据中的某些特征也可能使事情变得更高效。例如您可以使用apply(DF, 1, anyDuplicated)==0 删除没有任何重复值的行 - df 的维度是多少 - 是否有很多列组合,或者是列的长度?
  • Gavin,我认为 OP 正在尝试比较行,而不是列,而且您似乎在做相反的事情(我认为?)?
  • ADF &lt;- t(DF) 应该对它进行排序,除非我将其解释为一步的列和另一步的行,这是完全可能的!并且可能值得对 OPs 数据上最有效的基准进行基准测试,因为我们不知道它是长而细,还是短而宽,以及重复的普遍性等。
猜你喜欢
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多