避免传递数据框的最佳方法是啥?

Posted

技术标签:

【中文标题】避免传递数据框的最佳方法是啥?【英文标题】:What is the best way to avoid passing a data frame around?避免传递数据框的最佳方法是什么? 【发布时间】:2010-10-10 10:56:25 【问题描述】:

我有 12 个data.frames 可以使用。它们是相似的,我必须对每一个都做同样的处理,所以我写了一个函数,它接受一个data.frame,处理它,然后返回一个data.frame。这行得通。但我担心我正在绕过一个非常大的结构。我可能正在制作临时副本(是吗?)这效率不高。避免传递data.frame 的最佳方法是什么?

doSomething <- function(df) 
  // do something with the data frame, df
  return(df)

【问题讨论】:

后续问题:当完成 'doSomething' 时,命令 'rm(doSomething)' 将释放对象以进行垃圾回收,对吗? 但请记住,在上面的示例中,'doSomething' 是一个函数,而不是数据,所以它不是很大。 谢谢京东。你的答案很好。 不能通过引用传递数据帧吗? 【参考方案1】:

我在寻找其他内容时遇到了这个问题,而且它已经过时了 - 所以我现在只提供一个简短的答案(如果您需要更多解释,请发表评论)。

您可以在 R 中传递包含从 1 到所有变量的任何环境。但也许你不必担心。

[你也可以对类做类似的事情。我目前只了解如何将类用于多态函数 - 并注意有不止 1 个类系统在运行。]

【讨论】:

【参考方案2】:

我不是 R 专家,但大多数语言对大对象使用引用计数方案。在您修改对象的副本之前,不会生成对象数据的副本。如果您的函数只读取数据(即用于分析),则不应复制。

【讨论】:

【参考方案3】:

确实,您正在传递对象并使用一些内存。但我认为你不能在不传递对象的情况下对 R 中的对象进行操作。即使您没有创建函数并在函数之外进行操作,R 的行为也基本相同。

最好的方法是建立一个例子。如果您在 Windows 中,请打开 Windows 任务管理器。如果您在 Linux 中打开终端窗口并运行 top 命令。在此示例中,我将假设 Windows。在 R 中运行以下命令:

col1<-rnorm(1000000,0,1)
col2<-rnorm(1000000,1,2)
myframe<-data.frame(col1,col2)

rm(col1)
rm(col2)
gc()

这会创建一对名为 col1 和 col2 的向量,然后将它们组合成一个名为 myframe 的数据帧。然后它会丢弃向量并强制垃圾收集运行。在 Windows 任务管理器中查看 Rgui.exe 任务的内存使用情况。当我启动 R 时,它使用大约 19 兆内存。运行上述命令后,我的机器对 R 的使用量不到 35 兆。

现在试试这个:

myframe<-myframe+1

您的 R 内存使用量应该超过 144 兆。如果你使用 gc() 强制垃圾收集,你会看到它回落到大约 35 兆。要使用函数尝试此操作,您可以执行以下操作:

doSomething <- function(df) 
    df<-df+1-1
return(df)

myframe<-doSomething(myframe)

当您运行上面的代码时,内存使用量将跃升至 160 兆左右。运行 gc() 会将其降回 35 兆。

那么如何理解这一切呢?好吧,在函数之外执行操作(就内存而言)并不比在函数中执行操作更有效。垃圾收集清理东西真的很好。你应该强制 gc() 运行吗?可能不会,因为它会根据需要自动运行,我只是在上面运行它以显示它如何影响内存使用。

希望对你有帮助!

【讨论】:

以上是关于避免传递数据框的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

spark中将每个组作为新数据帧并在循环中传递另一个函数的最佳方法是啥?

将数组从 php 传递到 MySQL 存储过程的最佳方法是啥?

在线程之间传递信息的最佳方式是啥?

在 SwiftUI 中将绑定传递给导航堆栈中每个视图的最佳方法是啥

将变量从 node.js 文件传递​​到另一个文件的最佳方法是啥?

将信息从一个集合视图传递到另一个更详细的集合视图的最佳方法是啥