我的组似乎没有在磁盘框架中工作
My group by doesn't appear to be working in disk frames
我 运行 在一个大型数据集 (>20GB) 上分组,但它似乎工作不正常
这是我的代码
mydf[, .(value = n_distinct(list_of_id, na.rm = T)),
by = .(week),
keep = c("list_of_id", "week")
]
它返回了这个错误
Warning messages: 1: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 2: In
serialize(data, node$con) : 'package:MLmetrics' may not be available
when loading 3: In serialize(data, node$con) : 'package:MLmetrics'
may not be available when loading 4: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 5: In
serialize(data, node$con) : 'package:MLmetrics' may not be available
when loading 6: In serialize(data, node$con) : 'package:MLmetrics'
may not be available when loading 7: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 8: In
serialize(data, node$con) : 'package:MLmetrics' may not be available
when loading
我最初加载了库,但后来我 运行 remove.packages(MLmetrics) 在 运行 执行此代码之前。此外,我检查了 conflicted::conflict_scout,没有发现与 MLmetrics 包有任何冲突。
当我运行这段代码
> mydf %>%
+ filter(week == "2012-01-02")
它给了我这个输出
week value
1: 2012-01-02 483
2: 2012-01-02 61233
我担心在对数据进行分组时出现问题,因为它没有创建不同的价值周组。两列都存储为字符数据类型。
disk.frame
看起来很有趣,可以填补 RAM 处理和大数据之间的空白。
为了测试它,我创建了一个 200 * 200 Mb CSV 文件的集合,总计 40Gb,超过了我计算机上安装的 32Gb RAM:
library(furrr)
library(magrittr)
library(data.table)
library(dplyr)
library(disk.frame)
plan(multisession,workers = 11)
nbrOfWorkers()
#[1] 11
filelength <- 1e7
# Create 200 files * 200Mb
sizelist <- 1:200 %>% future_map(~{
mydf <- data.table(week = sample(1:52,filelength,replace=T),
list_of_id=sample(1:filelength,filelength,replace=T))
filename <- paste0('data/test',.x,'.csv')
data.table::fwrite(mydf, filename)
##write.csv(mydf,file=filename)
file.size(filename)
})
sum(unlist(sizelist))
# [1] 43209467799
由于distinct_n
是一个dplyr
动词,我先停留在dplyr
句法:
setup_disk.frame()
#The number of workers available for disk.frame is 6
options(future.globals.maxSize = Inf)
mydf = csv_to_disk.frame(file.path('data',list.files('data')))
"
csv_to_disk.frame: Reading multiple input files.
Please use `colClasses = ` to set column types to minimize the chance of a failed read
=================================================
-----------------------------------------------------
-- Converting CSVs to disk.frame -- Stage 1 of 2:
Converting 200 CSVs to 60 disk.frames each consisting of 60 chunks
Progress: ──────────────────────────────────────────────────────────────── 100%
-- Converting CSVs to disk.frame -- Stage 1 or 2 took: 00:01:44 elapsed (0.130s cpu)
-----------------------------------------------------
-----------------------------------------------------
-- Converting CSVs to disk.frame -- Stage 2 of 2:
Row-binding the 60 disk.frames together to form one large disk.frame:
Creating the disk.frame at c:\TempWin\RtmpkNkY9H\file398469c42f1b.df
Appending disk.frames:
Progress: ──────────────────────────────────────────────────────────────── 100%
Stage 2 of 2 took: 59.9s elapsed (0.370s cpu)
-----------------------------------------------------
Stage 1 & 2 in total took: 00:02:44 elapsed (0.500s cpu)"
result <- mydf %>%
group_by(week) %>%
summarize(value = n_distinct(list_of_id)) %>%
collect
result
# A tibble: 52 x 2
week value
<int> <int>
1 1 9786175
2 2 9786479
3 3 9786222
4 4 9785997
5 5 9785833
6 6 9786013
7 7 9786586
8 8 9786029
9 9 9785674
10 10 9786314
# ... with 42 more rows
原来如此!
用于此特定任务的总 RAM 内存在 1 到 5Gb 之间波动,在 6 个处理器上处理 20 亿行花费了不到 10 分钟的时间,限制因素似乎是磁盘访问速度而不是处理器性能。
我还用 data.table
语法进行了测试,因为 disk.frame
两者都接受,但我返回的速度太快了 60 倍多的行(好像 60 disk.frames 创建了200 个 CSV 未合并 and/or 完全处理),还有很多 Warning messages: 1: In serialize(data, node$con)
.
我在 GitHub 上提交了一个问题。
在弄清楚这一点之前,我建议继续使用有效的 dplyr
语法。
这个例子让我相信 disk.frame
允许处理比 RAM 更大的数据 supported verbs
此处为{disk.frame}的作者。
问题是目前,{disk.frame} 没有按 within
每个块分组。它不像 dplyr 语法那样在全局范围内执行 group-by。
所以你得再总结一遍,才能达到你想要的效果。所以我建议现在坚持使用 dplyr 语法。
正如@Waldi 指出的那样,{disk.frame}
的 dplyr 语法工作正常,目前缺少对 data.table 的支持,因此您现在只能使用 dplyr 语法实现您想要的。
{disk.frame} 需要实施 https://github.com/xiaodaigh/disk.frame/issues/239 才能适用于 data.table.
如果 anyone/organization 愿意资助此功能的开发,请私信我。
我 运行 在一个大型数据集 (>20GB) 上分组,但它似乎工作不正常
这是我的代码
mydf[, .(value = n_distinct(list_of_id, na.rm = T)),
by = .(week),
keep = c("list_of_id", "week")
]
它返回了这个错误
Warning messages: 1: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 2: In serialize(data, node$con) : 'package:MLmetrics' may not be available when loading 3: In serialize(data, node$con) : 'package:MLmetrics' may not be available when loading 4: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 5: In serialize(data, node$con) : 'package:MLmetrics' may not be available when loading 6: In serialize(data, node$con) : 'package:MLmetrics' may not be available when loading 7: In serialize(data, node$con) :
'package:MLmetrics' may not be available when loading 8: In serialize(data, node$con) : 'package:MLmetrics' may not be available when loading
我最初加载了库,但后来我 运行 remove.packages(MLmetrics) 在 运行 执行此代码之前。此外,我检查了 conflicted::conflict_scout,没有发现与 MLmetrics 包有任何冲突。
当我运行这段代码
> mydf %>%
+ filter(week == "2012-01-02")
它给了我这个输出
week value
1: 2012-01-02 483
2: 2012-01-02 61233
我担心在对数据进行分组时出现问题,因为它没有创建不同的价值周组。两列都存储为字符数据类型。
disk.frame
看起来很有趣,可以填补 RAM 处理和大数据之间的空白。
为了测试它,我创建了一个 200 * 200 Mb CSV 文件的集合,总计 40Gb,超过了我计算机上安装的 32Gb RAM:
library(furrr)
library(magrittr)
library(data.table)
library(dplyr)
library(disk.frame)
plan(multisession,workers = 11)
nbrOfWorkers()
#[1] 11
filelength <- 1e7
# Create 200 files * 200Mb
sizelist <- 1:200 %>% future_map(~{
mydf <- data.table(week = sample(1:52,filelength,replace=T),
list_of_id=sample(1:filelength,filelength,replace=T))
filename <- paste0('data/test',.x,'.csv')
data.table::fwrite(mydf, filename)
##write.csv(mydf,file=filename)
file.size(filename)
})
sum(unlist(sizelist))
# [1] 43209467799
由于distinct_n
是一个dplyr
动词,我先停留在dplyr
句法:
setup_disk.frame()
#The number of workers available for disk.frame is 6
options(future.globals.maxSize = Inf)
mydf = csv_to_disk.frame(file.path('data',list.files('data')))
"
csv_to_disk.frame: Reading multiple input files.
Please use `colClasses = ` to set column types to minimize the chance of a failed read
=================================================
-----------------------------------------------------
-- Converting CSVs to disk.frame -- Stage 1 of 2:
Converting 200 CSVs to 60 disk.frames each consisting of 60 chunks
Progress: ──────────────────────────────────────────────────────────────── 100%
-- Converting CSVs to disk.frame -- Stage 1 or 2 took: 00:01:44 elapsed (0.130s cpu)
-----------------------------------------------------
-----------------------------------------------------
-- Converting CSVs to disk.frame -- Stage 2 of 2:
Row-binding the 60 disk.frames together to form one large disk.frame:
Creating the disk.frame at c:\TempWin\RtmpkNkY9H\file398469c42f1b.df
Appending disk.frames:
Progress: ──────────────────────────────────────────────────────────────── 100%
Stage 2 of 2 took: 59.9s elapsed (0.370s cpu)
-----------------------------------------------------
Stage 1 & 2 in total took: 00:02:44 elapsed (0.500s cpu)"
result <- mydf %>%
group_by(week) %>%
summarize(value = n_distinct(list_of_id)) %>%
collect
result
# A tibble: 52 x 2
week value
<int> <int>
1 1 9786175
2 2 9786479
3 3 9786222
4 4 9785997
5 5 9785833
6 6 9786013
7 7 9786586
8 8 9786029
9 9 9785674
10 10 9786314
# ... with 42 more rows
原来如此! 用于此特定任务的总 RAM 内存在 1 到 5Gb 之间波动,在 6 个处理器上处理 20 亿行花费了不到 10 分钟的时间,限制因素似乎是磁盘访问速度而不是处理器性能。
我还用 data.table
语法进行了测试,因为 disk.frame
两者都接受,但我返回的速度太快了 60 倍多的行(好像 60 disk.frames 创建了200 个 CSV 未合并 and/or 完全处理),还有很多 Warning messages: 1: In serialize(data, node$con)
.
我在 GitHub 上提交了一个问题。
在弄清楚这一点之前,我建议继续使用有效的 dplyr
语法。
这个例子让我相信 disk.frame
允许处理比 RAM 更大的数据 supported verbs
此处为{disk.frame}的作者。
问题是目前,{disk.frame} 没有按 within
每个块分组。它不像 dplyr 语法那样在全局范围内执行 group-by。
所以你得再总结一遍,才能达到你想要的效果。所以我建议现在坚持使用 dplyr 语法。
正如@Waldi 指出的那样,{disk.frame}
的 dplyr 语法工作正常,目前缺少对 data.table 的支持,因此您现在只能使用 dplyr 语法实现您想要的。
{disk.frame} 需要实施 https://github.com/xiaodaigh/disk.frame/issues/239 才能适用于 data.table.
如果 anyone/organization 愿意资助此功能的开发,请私信我。