【发布时间】:2017-12-09 11:33:34
【问题描述】:
我正在尝试使用以下代码获取一些统计信息:
library(data.table)
df <- fread("input.xyz", header=F, sep = " ", stringsAsFactors = F)
df2 <- read.table("input2.xyz", header=F, sep = " ", stringsAsFactors = F)
df2 <- df2[-which(df2$V3 == 0),]
long <- df2$V1
lat <- df2$V2
fin_mtx <- matrix(NA, nrow=18976, ncol=8)
colnames(fin_mtx) <- c("Longitude", "Latitude", "Mean", "Median", "Std Dev",
"Max", "Min", "No. of NA")
fin_mtx <- as.data.frame(fin_mtx)
i = 1
while (i < 18976)
{
px_vl <- subset(df$V3, (df$V1 > long[i] - 0.125/2) & (df$V1 < long[i] + 0.125/2) &
(df$V2 < lat[i] + 0.125/2) & (df$V2 > lat[i] - 0.125/2))
frq <- as.data.frame(table(px_vl))
if (frq[1,1] == -32768) {
fin_mtx[i,8] <- frq[which(frq$px_vl==-32768),2]
px_vl[px_vl == -32768] <- NA
}
fin_mtx[i,1] <- long[i]
fin_mtx[i,2] <- lat[i]
fin_mtx[i,3] <- mean(px_vl, na.rm = T)
fin_mtx[i,4] <- median(px_vl, na.rm = T)
fin_mtx[i,5] <- sd(px_vl, na.rm = T)
fin_mtx[i,6] <- max(px_vl, na.rm = T)
fin_mtx[i,7] <- min(px_vl, na.rm = T)
i = i + 1
}
df 有近 1.72 亿行和三列,而 df2 有 18,976 行。运行代码需要很长时间(我的意思是几天)。此外,使用了大量的内存。我想减少这个时间和计算负载。我参考了一些建议,例如预先定义向量并在不同的教程中使用data.table,但它们并没有太大帮助。
【问题讨论】:
-
请分享几行任一数据集。我敢打赌这条无辜的线是瓶颈:
frq <- as.data.frame(table(px_vl))在每次迭代中的所有列中的 1.72 亿行查找频率!史诗。只需table(head(mtcars))创建 65,333 个矩阵切片!并且绑定为data.frame会返回内存错误。 -
另外请用文字描述您的代码在做什么。对于 1/8 度网格,您正在计算
px_vl的汇总统计信息,但我不确定您的if (frq[1,1] == -32768)的内容在做什么。 -
@Parfait
px_vl <- subset(df$V3, (df$V1 > long[i] - 0.125/2) & (df$V1 < long[i] + 0.125/2) & (df$V2 < lat[i] + 0.125/2) & (df$V2 > lat[i] - 0.125/2))花费的时间最多。我跑 i=1 时大约超过 25 秒 -
@Gregor 我正在尝试计算更高分辨率网格的统计数据,以将其转换为 1/8 度。 -32768 是我实际需要计算的 df 中 NA 数据的值
-
您应该使用分组数据表操作。现在,对于每次迭代,您都在计算圆角网格以找到子集,进行昂贵的数据框转换,然后计算您的统计数据。您需要在开头添加一次分组列,也许在开头将
-32768替换为NA一次,然后使用使用数据表.SD。正如其他人所说,分享一些小的示例数据,我们可以提供帮助。最好共享代码来模拟大约 100 行具有正确结构的数据。
标签: r performance while-loop data.table