我正在尝试扩展一个大矩阵(我实际使用的矩阵要大得多):
x = matrix(rnorm(1e8), nrow=1e4)
x = scale(x)
Run Code Online (Sandbox Code Playgroud)
该矩阵使用~800 MB的内存.但是,使用lineprof,我看到scale函数分配了9.5 GB的内存,并在完成运行后释放8.75 GB.因为这个函数的内存效率很低,所以当我运行它时,它有时会崩溃我的会话.
我试图找到一种内存有效的方法来运行此功能.如果我自己编写代码,它只分配~6.8 GB,但这看起来仍然很多:
x = matrix(rnorm(1e8), nrow=1e4)
u = apply(x, 2, mean)
s = apply(x, 2, sd)
x = t((t(x) - u)/s)
Run Code Online (Sandbox Code Playgroud)
我认为通过将x列分成组,然后分别缩放每个列组,我可以做得更好:
x = matrix(rnorm(1e8), nrow=1e4)
g = split(1:ncol(x), ceiling(1:ncol(x)/100))
for(j in g){
x[,j] = scale(x[,j])
}
Run Code Online (Sandbox Code Playgroud)
有了profvis,我发现总的来说这个功能效率很低.它分配10.8 GB内存并释放10.5 GB.但是,我认为R可能在for循环中进行垃圾收集,但它不是这样做的,因为它不需要.它是否正确?如果是这样,那么这可能是最好的选择吗?
问题:
• 编写这些函数以避免内存崩溃的最佳方法是什么?(如果包装可用,甚至更好)
• 在分析代码时如何计算垃圾回收?我的理解是,除非需要,否则GC并不总是运行.
更新:就运行时而言,将列拆分为10组并不比使用scale(x)函数慢得多.在[1000 x 1000]矩阵上运行两个函数,使用微基准测试评估的平均运行时间为:
•scale(x)= 154 ms
•拆分为10个列组= 167毫秒
•拆分为1000个列组(即分别缩放每列)= 373 ms
题
我的默认 Python 是 2.7,但我有一个需要 Python 3.4 的脚本。我正在尝试在 R 中创建一个函数,它将:
要在 Python 版本之间切换,我使用集群的“dotkit”系统,如下所示:
use Python-2.7
use Python-3.4
Run Code Online (Sandbox Code Playgroud)
“use”是一个导入到我的 .bashrc 文件中的 bash 函数。它设置了我所有的路径变量(PATH、LIBRARY_PATH、LD_LIBRARY_PATH、CPATH、C_INCLUDE_PATH 等)。问题是,当我尝试在 R 中调用此函数时,出现以下错误:
system('use Python-3.4')
sh: use: command not found
Run Code Online (Sandbox Code Playgroud)
这似乎是我的 PATH 的问题。我正在使用正确的外壳:
system('echo $SHELL')
/bin/bash
Run Code Online (Sandbox Code Playgroud)
我的 $PATH 变量看起来也不错。但是,当我创建一个基本上执行相同操作的脚本时:
load_py34.sh:
#!/bin/bash
source ~/.bashrc
use Python-3.4
Run Code Online (Sandbox Code Playgroud)
并通过 R 调用此脚本,然后它实际运行,但由于某种原因,它不会更改我在 R 中的 Python 版本。(我已验证此脚本可从命令行运行。)
> R
> system('python --version')
Python 2.7.1
> system('sh load_py34.sh')
Prepending: R-3.4 (ok)
> system('python --version')
Python …Run Code Online (Sandbox Code Playgroud) 以下是R中"ave"函数的源代码:
function (x, ..., FUN = mean)
{
if (missing(...))
x[] <- FUN(x)
else {
g <- interaction(...)
split(x, g) <- lapply(split(x, g), FUN)
}
x
}
Run Code Online (Sandbox Code Playgroud)
我无法理解赋值"split(x,g)< - lapply(split(x,g),FUN)"是如何工作的.请考虑以下示例:
# Overview: function inputs and outputs
> x = 10*1:6
> g = c('a', 'b', 'a', 'b', 'a', 'b')
> ave(x, g)
[1] 30 40 30 40 30 40
# Individual components of "split" assignment
> split(x, g)
$a
[1] 10 30 50
$b
[1] 20 40 60
> lapply(split(x, …Run Code Online (Sandbox Code Playgroud)