【发布时间】:2014-11-23 18:52:27
【问题描述】:
我有两张桌子。一个有 2012 年到 2014 年的信息,时间为 3 小时。它看起来像这样:
B C
1 01.06.2012 00:00 10 0
2 01.06.2012 03:00 10 0
3 01.06.2012 06:00 10 6
4 01.06.2012 09:00 7,5 0
5 01.06.2012 12:00 6 2,5
6 01.06.2012 15:00 6 0
7 01.06.2012 18:00 4 0
8 01.06.2012 21:00 4 0
9 02.06.2012 00:00 0 0
10 02.06.2012 03:00 0 0
另一张表时间相同但按1分钟采样:
1 01.06.2012 00:00
2 01.06.2012 00:01
3 01.06.2012 00:01
4 01.06.2012 00:03
5 01.06.2012 00:03
6 01.06.2012 00:05
7 01.06.2012 00:05
8 01.06.2012 00:07
9 01.06.2012 00:08
10 01.06.2012 00:09
11 01.06.2012 00:10
现在,我需要第二个表的第 2 行和第 3 行的值与第一个表相关联,这样如果第二个表的时间戳介于第一个表的 timestamp(i) 和 timestamp(i+1) 之间,它将采用B(i) 和 C(i) 并复制它们。我有这段代码,我知道它可以工作,但是运行它需要超过 12 个小时,而且我有很多这样的文件需要以同样的方式处理。
clouds <- read.csv('~/2012-2014 clouds info.csv', sep=";", header = FALSE)
cloudFull <- read.csv('~/2012-2014 clouds.csv', sep=";", header = FALSE)
for (i in 1:nrow(cloudFull)){
dateOne <- strptime(cloudFull[i,1], '%d.%m.%Y %H:%M')
for (j in 1:nrow(clouds)){
bottomDate = strptime(clouds[j,1], '%d.%m.%Y %H:%M')
upperDate = strptime(clouds[j+1,1], '%d.%m.%Y %H:%M')
if ((dateOne >= bottomDate) && (dateOne < upperDate)) {
cloudFull[i,2] <- clouds[j,2]
cloudFull[i,3] <- clouds[j,3]
break
}
}
}
write.csv(cloudFull, file = 'cc.csv')
现在如何让它运行得更快? object.size(cloudFull) 给了我39580744 字节,它有470000 行,但其他文件会有更多数据。我刚从 R 开始(到目前为止只在其中工作了 2 天),我将不胜感激以非常简单的语言提供任何建议:D
【问题讨论】:
-
您将
cloudfull中的每一行与cloud中的每一行进行比较。如果两者都有 470000 个条目,则比较 470000*470000,这很多。假设两个输入文件都按日期时间顺序排序,然后对“合并”两个文件进行一些研究。 -
AdrianHHH 是对的,它不是 R 特定的,它是关于通用算法的。使用某种索引来减少搜索时间。不要使用 for 循环,您使用的是复杂度为 o(n^2) 的算法。一个排序表应该把它带到 o(n log(n)),如果你能负担得起,只需制作一个直数组(因为你的数据是等距的,没有空洞)使它成为 o(n)
-
cloud 按 3 小时采样,而 cloudFull 按 1 分钟采样,这意味着云要小 180 倍。但我会考虑“合并”,谢谢!
-
使用包 data.table 并进行滚动连接。 (此外,您正在为循环内的单个值调用
strptime。您可以使用循环外的整个向量来执行此操作。事实上,如果您使用向量化,则不需要内部循环。) -
在for循环外提升向量化操作,例如循环外
dateOne <- strptime(cloudFull[,1], '%d.%m.%Y %H:%M'),内dateOne[i];对于其他strptime()调用也是如此。findInterval()是一种将细粒度数据放入(排序)箱的有效方法;与时俱进可能需要一些技巧。
标签: r performance for-loop rstudio