获取xml属性花费的时间太长,而且内存密集R
问题描述:
我想从我的xml文件(下面显示的是我的文件的示例)中匹配某些模式的所有xml属性中读取。实际的xml文件大小约为400 MB,具有约450万行xml节点和属性。获取xml属性花费的时间太长,而且内存密集R
<?xml version="1.0" encoding="utf-8"?>
<events version="1.0">
\t <event time="10800.0" type="actend" person="9982471" link="21225" actType="home" />
\t <event time="10800.0" type="departure" person="9982471" link="21225" legMode="car" />
\t <event time="10800.0" type="PersonEntersVehicle" person="9982471" vehicle="9982471" />
\t <event time="10800.0" type="actend" person="9656271" link="21066" actType="home" />
\t <event time="10800.0" type="departure" person="9656271" link="21066" legMode="car" />
\t <event time="10800.0" type="PersonEntersVehicle" person="9656271" vehicle="9656271" />
\t <event time="99489.0" type="entered link" person="10777221" link="14182" vehicle="10777221" />
\t <event time="99498.0" type="left link" person="10777221" link="14182" vehicle="10777221" />
\t <event time="99498.0" type="entered link" person="10777221" link="14128" vehicle="10777221" />
\t <event time="99533.0" type="left link" person="10777221" link="14128" vehicle="10777221" />
\t <event time="99533.0" type="entered link" person="10777221" link="14122" vehicle="10777221" />
\t <event time="99542.0" type="left link" person="10777221" link="14122" vehicle="10777221" />
\t <event time="99542.0" type="entered link" person="10777221" link="14100" vehicle="10777221" />
</events>
这是我使用提取感兴趣的数据框的代码。
library(XML) file <- "C:/Users/S/Desktop/100.events.test.xml" popact <- xmlParse(file) eventsdf <- sapply(c("time","type", "person", "link", "vehicle"), function(x) xpathSApply(popact, "//event[@type='left link']|//event[@type='entered link']", xmlGetAttr, x))
这里是我所面临的问题:没有仍能产生结果的代码已经运行了几个小时
- 。有趣的是,如果我删除限定符
"//event[@type='left link']|//event[@type='entered link']"
并使用"//event"
(即读取没有特定选择的所有属性),我会在大约半小时内获得结果。我怎样才能减少我的代码的运行时间?我应该用不同的方法来获得我需要的结果吗? - 尽管在这种情况下文件的大小仅为400 MB,但在集群上运行代码时,代码需要大约11 GB的RAM。为什么使用XML文件和使用XML库如此密集的内存?这对我来说非常重要,因为我有一个大小为40 GB的类似文件。简单的信封计算表明,我可能需要1200 GB的RAM来处理这个大文件。是否有任何技术来管理内存需求?
答
sapply
只有在某些节点缺少属性时才需要。如果没有,如示例中所示,我们可以将其简化为以下内容,其中xpath
是您的XPath表达式。此外,这里的xpath表达式仅遍历节点树,因为只有一个//
。
xpath2 <- "//event[@type='left link' or @type='entered link']"
t(xpathSApply(popact, xpath2, xmlAttrs))
这里是一个定时比较:
library(rbenchmark)
xpath <- "//event[@type='left link']|//event[@type='entered link']"
benchmark(orig = sapply(c("time","type", "person", "link", "vehicle"),
function(x) xpathSApply(popact, xpath, xmlGetAttr, x)),
new = t(xpathSApply(popact, xpath2, xmlAttrs)))[1:4]
,并提供:
test replications elapsed relative
2 new 100 0.07 1.000
1 orig 100 0.68 9.714
感谢您的答复。尽管它有帮助,但并未解决性能问题。代码运行几个小时而没有产生最终结果。 7小时后我停了下来。什么似乎更好的工作是使用'xpath Gandalf
这是我使用的代码和运行时间。 'library(XML) file Gandalf
感谢Gabor。你能把这个作为一个单独的答案,以便我可以接受吗?另外,为什么这个速度比我使用的要快很多,有些解释是很好的。 – Gandalf