获取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))

这里是我所面临的问题:没有仍能产生结果的代码已经运行了几个小时

  1. 。有趣的是,如果我删除限定符"//event[@type='left link']|//event[@type='entered link']"并使用"//event"(即读取没有特定选择的所有属性),我会在大约半小时内获得结果。我怎样才能减少我的代码的运行时间?我应该用不同的方法来获得我需要的结果吗?
  2. 尽管在这种情况下文件的大小仅为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 
+0

感谢您的答复。尽管它有帮助,但并未解决性能问题。代码运行几个小时而没有产生最终结果。 7小时后我停了下来。什么似乎更好的工作是使用'xpath Gandalf

+0

这是我使用的代码和运行时间。 'library(XML) file Gandalf

+0

感谢Gabor。你能把这个作为一个单独的答案,以便我可以接受吗?另外,为什么这个速度比我使用的要快很多,有些解释是很好的。 – Gandalf