这个问题与我提出的另一个问题有关here。
我的数据框包含每0.1秒时间帧内车辆的速度和加速度。以下显示数据框的数据点非常少,最初包含超过1,000,000行:
> dput(head(traj2[, c(1,2,12,13)], 30))
structure(list(Vehicle.ID = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 1L), Frame.ID = 270:299, Vehicle.velocity = c(19.89,
19.89, 19.89, 19.89, 19.89, 19.97, 20, 19.86, 19.18, 18.17, 17.63,
17.87, 18.76, 19.67, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 19.99, 19.98), Vehicle.acceleration = c(0, 0,
0, 0, 1.07, 0.6, 0, -2.42, -9.79, -11.2, -2.64, 9.2, 11.2, 5.32,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0.11, -0.2)), .Names = c("Vehicle.ID",
"Frame.ID", "Vehicle.velocity", "Vehicle.acceleration"), row.names = c(NA,
30L), class = "data.frame")
请注意,大约有2000个唯一Vehicle.ID
个,每个都以不同的帧数重复。
我想通过使用第一个问题中提供的等式来平滑速度和加速度。但我希望尽可能缩短时间并使代码尽可能高效。
我使用以下代码进行平滑处理:
# VELOCITY SMOOTHING FUNCTION
smooth <- function (x, D, delta){
z <- exp(-abs(-D:D/delta))
r <- convolve (x, z, type='filter')/convolve(rep(1, length(x)),z,type='filter')
r
}
# ACCELERATION SMOOTHING FUNCTION
smootha <- function (x, D, delta){
za <- exp(-abs(-D:D/delta))
ra <- convolve (x, za, type='filter')/convolve(rep(1, length(x)),za,type='filter')
ra
} ### D=3*delta = 3*40 = 120, delta for acceleration = T / dt = 4 seconds/0.1 = 40
ftaa <- list()
# Split data by vehicle ID
length(ftaa) <- length(unique(traj1$'Vehicle.ID'))
# Apply smoothing function
for (i in 1:length(unique(traj2$'Vehicle.ID'))){
veh <- subset (traj2, traj2$'Vehicle.ID'==unique(traj2$'Vehicle.ID')[i])
svel <- round(smooth(veh$'Vehicle.velocity',30,10), digits=2)
svel <- data.frame(svel)
svel <- head(tail(svel,-90),-90)
sacc <- round(smootha(veh$'Vehicle.acceleration',120,40), digits=2)
sacc <- data.frame(sacc)
veh <- head(tail(veh, -120), -120)
ftaa[[i]] <- cbind(veh,svel,sacc)
}
# Combining results
final.data1<-do.call("rbind", ftaa)
这种方法大约需要40分钟才能完成给定数据框的平滑。有什么方法可以减少这个时间吗?
答案 0 :(得分:2)
我强烈建议放弃循环并使用data.table
。另外,为什么不在round
和smooth
函数中使用smootha
函数?
require(data.table)
setDT(traj2)
traj2[ , svel := smooth(Vehicle.velocity,30,10), by =Vehicle.ID]
traj2[ , sacc := smootha(Vehicle.acceleration,120,40), by =Vehicle.ID]
这很难测试,因为您的问题不是以可重现的方式设置的。您的平滑函数需要具有相同大小的向量(您的链接显示使用与type="open"
的卷积而不是您使用它的方式)。但这是一个很好的模板,可以让你的代码运行得更快。