gpt4 book ai didi

r - 按升序/降序快速对 data.table 进行排序

转载 作者:行者123 更新时间:2023-12-01 18:25:28 28 4
gpt4 key购买 nike

我有一个大约有 300 万行和 40 列的 data.table。我想按组内的降序对该表进行排序,如以下 sql 模拟代码:

sort by ascending Year, ascending MemberID, descending Month 

data.table 中是否有等效的方法来执行此操作?到目前为止,我必须将其分为两个步骤:

setkey(X, Year, MemberID)

这非常快,只需要几秒钟。

X <- X[,.SD[order(-Month)],by=list(Year, MemberID)]

此步骤需要更长的时间(5 分钟)。

更新:有人评论要做X <- X[sort(Year, MemberID, -Month)]后来删除了。这种方法似乎要快得多:

user  system elapsed 
5.560 11.242 66.236

我的方法:setkey() 然后 order(-Month)

   user  system elapsed 
816.144 9.648 848.798

我现在的问题是:如果我想在排序后按年、成员(member)ID和月进行汇总(年、成员(member)ID、月),data.table是否能识别排序顺序?

更新 2:回应 Matthew Dowle:

在 setkey 包含年份、成员(member) ID 和月份之后,我每个组仍然有多个记录。我想对每个组进行总结。我的意思是:如果我使用 X[order(Year, MemberID, Month)],求和是否利用 data.table 的二进制搜索功能:

monthly.X <- X[, lapply(.SD[], sum), by = list(Year, MemberID, Month)]

更新 3:Matthew D 提出了几种方法。第一种方法的运行时间比 order() 方法更快:

   user  system elapsed 
7.910 7.750 53.916

Matthew:令我惊讶的是转换月份的符号花费了大部分时间。没有它,setkey 的速度会非常快。

最佳答案

2014 年 6 月 5 日更新:

当前开发版本的data.table v1.9.3实现了两个新函数,即:setordersetorderv,它们完全可以满足您的需求。这些函数通过引用对 data.table 进行重新排序,并且可以选择在每列上按升序或降序进行排序。查看 ?setorder 了解更多信息。

此外,DT[order(.)] 默认情况下也经过优化,可以使用 data.table内部快速顺序来代替base:::order。与 setorder 不同,这将创建数据的完整副本,因此内存效率较低,但仍比使用基本顺序进行操作要快几个数量级。

基准:

下面是使用 setorder(data.table 的内部快速顺序)和 base:::order 的速度差异的说明:

require(data.table) ## 1.9.3
set.seed(1L)
DT <- data.table(Year = sample(1950:2000, 3e6, TRUE),
memberID = sample(paste0("V", 1:1e4), 3e6, TRUE),
month = sample(12, 3e6, TRUE))

## using base:::order
system.time(ans1 <- DT[base:::order(Year, memberID, -month)])
# user system elapsed
# 76.909 0.262 81.266

## optimised to use data.table's fast order
system.time(ans2 <- DT[order(Year, memberID, -month)])
# user system elapsed
# 0.985 0.030 1.027

## reorders by reference
system.time(setorder(DT, Year, memberID, -month))
# user system elapsed
# 0.585 0.013 0.600

## or alternatively
## setorderv(DT, c("Year", "memberID", "month"), c(1,1,-1))

## are they equal?
identical(ans2, DT) # [1] TRUE
identical(ans1, ans2) # [1] TRUE

根据此数据,基准测试表明 data.table 的 order 比 base:::order 大约快 79 倍,并且 setorder 为 <比此处的 base:::order 快约 135 倍。

data.table 始终以 C 语言环境进行排序/排序。如果您需要在其他语言环境中订购,那么您才需要使用 DT[base:::order(.)]

所有这些新的优化和功能共同构成了FR #2405bit64::integer64 support also has been added .

<小时/>

NOTE: Please refer to the history/revisions for earlier answer and updates.

关于r - 按升序/降序快速对 data.table 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13685295/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com