我试图从我的 xml 文件中读取与特定模式匹配的所有 xml 属性(下面显示的是我的文件的示例)。实际的 xml 文件大小约为 400 MB,包含约 450 万行 xml 节点和属性。
<?xml version="1.0" encoding="utf-8"?>
<events version="1.0">
<event time="10800.0" type="actend" person="9982471" link="21225" actType="home" />
<event time="10800.0" type="departure" person="9982471" link="21225" legMode="car" />
<event time="10800.0" type="PersonEntersVehicle" person="9982471" vehicle="9982471" />
<event time="10800.0" type="actend" person="9656271" link="21066" actType="home" />
<event time="10800.0" type="departure" person="9656271" link="21066" legMode="car" />
<event time="10800.0" type="PersonEntersVehicle" person="9656271" vehicle="9656271" />
<event time="99489.0" type="entered link" person="10777221" link="14182" vehicle="10777221" />
<event time="99498.0" type="left link" person="10777221" link="14182" vehicle="10777221" />
<event time="99498.0" type="entered link" person="10777221" link="14128" vehicle="10777221" />
<event time="99533.0" type="left link" person="10777221" link="14128" vehicle="10777221" />
<event time="99533.0" type="entered link" person="10777221" link="14122" vehicle="10777221" />
<event time="99542.0" type="left link" person="10777221" link="14122" vehicle="10777221" />
<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
关于xml - 在 R 中获取 xml 属性花费的时间太长并且占用大量内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668115/