我有一个大型数据框(大约几GB),我想转换为data.table
.使用as.data.table
创建数据框的副本,这意味着我需要的可用内存至少是数据大小的两倍.有没有办法在没有副本的情况下进行转换?
这是一个简单的示例来演示:
library(data.table)
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))
gc(reset=TRUE)
tracemem(data)
data <- as.data.table(data)
gc()
Run Code Online (Sandbox Code Playgroud)
随着输出:
library(data.table)
# data.table 1.8.10 For help type: help("data.table")
N <- 1e6
K <- 1e2
data <- as.data.frame(rep(data.frame(rnorm(N)), K))
gc(reset=TRUE)
# used (Mb) gc trigger (Mb) max used (Mb)
# Ncells 303759 16.3 597831 32.0 303759 16.3
# Vcells 100442572 766.4 402928632 3074.2 100442572 766.4
tracemem(data)
# [1] "<0x363fda0>"
data <- as.data.table(data)
# tracemem[0x363fda0 -> 0x31e4260]: copy …
Run Code Online (Sandbox Code Playgroud) 我有一个相对较大的DataFrame对象(大约一百万行,数百列),我想按组剪切每列中的异常值.通过"按组分组每个列的异常值"我的意思是 - 计算组中每列的5%和95%分位数,并剪切该分位数范围之外的值.
这是我目前正在使用的设置:
def winsorize_series(s):
q = s.quantile([0.05, 0.95])
if isinstance(q, pd.Series) and len(q) == 2:
s[s < q.iloc[0]] = q.iloc[0]
s[s > q.iloc[1]] = q.iloc[1]
return s
def winsorize_df(df):
return df.apply(winsorize_series, axis=0)
Run Code Online (Sandbox Code Playgroud)
然后,通过我的DataFrame调用features
和索引DATE
,我可以做到
grouped = features.groupby(level='DATE')
result = grouped.apply(winsorize_df)
Run Code Online (Sandbox Code Playgroud)
这是有效的,除了它非常慢,可能是由于嵌套apply
调用:每个组一个,然后每个组中的每个列一个.我试图apply
通过一次计算所有列的分位数来摆脱第二个,但是试图将每个列的阈值设置为不同的值.有没有更快的方法来完成此过程?
我试图通过将所有必要的依赖项(函数和数据)加载到新环境中并在该环境中评估表达式,以沙盒方式运行一大块R代码.但是,我在调用环境中的其他函数时遇到了麻烦.这是一个简单的例子:
jobenv <- new.env(parent=globalenv())
assign("f1", function(x) x*2, envir=jobenv)
assign("f2", function(y) f1(y) + 1, envir=jobenv)
expr <- quote(f2(3))
Run Code Online (Sandbox Code Playgroud)
使用eval
on expr
失败,因为f2
找不到f1
> eval(expr, envir=jobenv)
Error in f2(3) : could not find function "f1"
Run Code Online (Sandbox Code Playgroud)
而明确附加环境是有效的
> attach(jobenv)
> eval(expr)
[1] 7
Run Code Online (Sandbox Code Playgroud)
我可能错过了一些明显的东西,但我找不到任何有效的eval
呼叫排列.有没有办法在不附加环境的情况下获得相同的效果?
我在组中使用按组引用分配时看到奇数内存使用情况data.table
.这是一个简单的示例(请原谅示例的无关紧要):
N <- 1e6
dt <- data.table(id=round(rnorm(N)), value=rnorm(N))
gc()
for (i in seq(100)) {
dt[, value := value+1, by="id"]
}
gc()
tables()
Run Code Online (Sandbox Code Playgroud)
产生以下输出:
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 303909 16.3 597831 32.0 407500 21.8
Vcells 2442853 18.7 3260814 24.9 2689450 20.6
> for (i in seq(100)) {
+ dt[, value := value+1, by="id"]
+ }
> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 315907 16.9 597831 32.0 407500 21.8 …
Run Code Online (Sandbox Code Playgroud)