R数据表优化。透支财务数据

R数据表优化。透支财务数据,r,performance,data.table,financial,R,Performance,Data.table,Financial,给出以下数据表和财务数据(3500万行): DT: 本案: a、 -按用户ID列出的最大连续透支天数的总数 userId maxConsecutiveOverdraftDays 600 2 700 3 800 0 900 1 1000 5 在本例中,我执行了以下操作: acum = FALSE for (i in 1:nrow(DT)) { if (DT[i]$overdraft == 1 ) { if (acum == T

给出以下数据表和财务数据(3500万行):

DT:

本案:

a、 -按用户ID列出的最大连续透支天数的总数

userId  maxConsecutiveOverdraftDays   
600     2
700     3
800     0
900     1
1000    5
在本例中,我执行了以下操作:

acum = FALSE

for (i in 1:nrow(DT)) {

    if (DT[i]$overdraft == 1 ) {
      if (acum == TRUE) 
  {

        DT[i]$acumBalance <- DT[i]$balance + DT[i-1]$balance 
        DT[i]$totalConsecutiveOverdraftDays   <- DT[i]$overdraft + DT[i-1]$overdraft
  }

      if (DT[i]$userId == DT[i+1]$userId 
      && DT[i+1]$overdraft == 1 ) 
  {

        acum = TRUE
  }  
    else { acum = FALSE }
}
}

DT[,maxConsecutiveOverdraftDays:=max(totalConsecutiveOverdraftDays),by=userId]
acum=FALSE
对于(1中的i:nrow(DT)){
如果(DT[i]$透支==1){
如果(acum==真)
{

DT[i]$acumBalance无法说明这是否有助于解决您的性能问题,但
rle
在这里有助于编写漂亮的短代码。由于透支值始终为零或一,我们可以取长度和值乘积的最大值:

> aggregate(overdraft~userId, df, FUN=function(x) {
+   r <- rle(x)
+   max(r$lengths * r$values)
+ })
  userId overdraft
1    600         2
2    700         3
聚合(透支~userId,df,FUN=function(x){ +r更新:现在在中实现。从: 7)
rleid()
,一个方便的函数,用于生成用于分组操作的运行长度类型id列。关闭。有关使用场景,请检查
?rleid
示例部分

使用此功能,我们可以执行以下操作:

require(data.table) ## 1.9.5+
dt[, .(overdraft = overdraft[1L], .N), by=.(userId, 
      rleid(overdraft))][overdraft == 1L, max(N), by=userId]

实现这样一个函数有一个开放的方法。但这必须与快速排名函数一起实现。我们还没有实现它

在此之前,您可以这样做:

dt[, .(overdraft = overdraft[1L], .N), by=.(userId, 
    cumsum(c(TRUE, diff(overdraft) != 0L)))][overdraft == 1L, max(N), by=userId]
#    userId V1
# 1:    600  2
# 2:    700  3

编辑:更正了@Dirk指出的逻辑。谢谢!

这一行应该可以做到:

overdraft[, daysoverdraft:=seq(.N)-1, by=cumsum(overdraft == 0)]
让我们用一组简单的数据进行测试:

overdraft = data.table(userId=rep(1:10^3, each=350),
                       date=rep(1:350, 10^3),
                       balance=round(rnorm(35*10^3)*100),
                       overdraft=0)
overdraft[balance < 0, overdraft:=1]
overdraft=data.table(userId=rep(1:10^3,每个=350),
日期=代表(1:350,10^3),
平衡=圆形(规则(35*10^3)*100),
透支=0)
透支[余额<0,透支:=1]

它有350k行,运行速度可以接受(在我的笔记本电脑上大约1.2秒),但是,甚至没有接近Arun的回答速度,至少快20倍。

data.table
adaption:
DT[,rle(透支),by=userId][,max(长度*值),by=userId]
proc.time()-计时器用户系统运行时间为6.90 0.28 7.1812小时到7秒?Whoa.proc.time()-计时器用户系统运行时间为6.90 0.28 7.18
overdraft = data.table(userId=rep(1:10^3, each=350),
                       date=rep(1:350, 10^3),
                       balance=round(rnorm(35*10^3)*100),
                       overdraft=0)
overdraft[balance < 0, overdraft:=1]