繁体   English   中英

通过过滤加速data.table笛卡尔积

[英]speeding up a data.table cartesian product with filtering

给定一个data.table其中包含三个字段member_idprovider_idsrvc_dt 我需要计算一对提供者看到的不同成员的数量。 据说,如果访问发生在180天内,则会员访问过两家提供商。 这用于使用#visits的阈值构建无向图并查找连接的组件。

我正在使用笛卡尔积中建议的方法和过滤器data.table

我需要运行的实例有超过300万条记录,运行时间超过5分钟。 有没有一种重写方式或新的data.table函数,以便它运行得更快?

require(data.table)

nmem <- 5000
data.dt <- data.table(member_id=sample(10000:1000000,nmem,replace=TRUE), provider_id=sample(1000:2000,nmem,replace=TRUE),
    srvc_dt=sample(seq(as.Date('2014/01/01'), as.Date('2015/01/01'), by="day"), nmem, replace=TRUE))
setkey(data.dt, member_id)

prov_pair.dt <- data.dt[data.dt, {
        idx = provider_id<i.provider_id & abs(srvc_dt-i.srvc_dt)<180
        list(provider_id1 = provider_id[idx], 
            srvc_dt1 = srvc_dt[idx],
            provider_id2 = i.provider_id[any(idx)],
            srvc_dt2 = i.srvc_dt[any(idx)]
        )
    }, by=.EACHI, allow=TRUE]

prov_pair_agg.dt <- prov_pair.dt[, .(weight=length(unique(member_id))), .(provider_id1,provider_id2)]

简单的左连接然后过滤:

prov_pair.dt <- data.dt[data.dt,allow.cartesian=T][provider_id<i.provider_id &
  abs(srvc_dt-i.srvc_dt)<180,]

provider_id<i.provider_id防止重复计算对x,y和y,x的相同访问次数。

另外,现在在计算prov_pair_agg.dt使用provider_idi.provider_id而不是provider_id1provider_id2

prov_pair_agg.dt <- prov_pair.dt[, .(weight=length(unique(member_id))), 
  .(provider_id,i.provider_id)]

在ngm = 1,000,000的16GB内存机器上,按当前方法,这需要1.487s和106.034s。

首先,过滤掉数据,使其仅包含已经看过多个提供者的成员:

res = data.dt[, if (.N >= 2) .SD, by = member_id]

然后,添加日期的端点和提供者列的副本:

res[, `:=`(start.date = srvc_dt - 180,
           end.date   = srvc_dt + 180,
           provider2  = provider_id)]

最后,使用开发版中提供的新的非equi连接:

res[res, on = .(member_id = member_id, provider2 < provider_id,
                srvc_dt < end.date, srvc_dt > start.date)
    , allow = T, nomatch = 0][, .N, by = .(provider1 = provider_id, provider2)]

一个注意事项 - 上面的连接中的列名称目前很遗憾有点令人困惑,希望很快就能解决。 如果上面的内容太不清楚,您可以添加列的额外副本以查看究竟发生了什么。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM