2016-02-27 27 views
2

我想從我的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來處理這個大文件。是否有任何技術來管理內存需求?

回答

2

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 < - 「// event」',並使用 'eventsdf < - subset(eventsdf,eventsdf [,'type'] ==「left link」| eventsdf [ 'type'] ==「輸入鏈接」) 您能否就使用早期xpath非常緩慢的原因提出任何見解? – Gandalf

+0

這是我使用的代碼和運行時間。 'library(XML) file < - 「C:/Users/S/Desktop/100.events.test.xml」 popact < - xmlParse(file) eventsdf < - sapply(c(「time」,「類型「,」人「,」鏈接「,」車輛「),函數(x)xpathSApply(popact,」// event「,xmlGetAttr,x)) eventsdf < - subset(eventsdf,eventsdf [,'type'] ==「left link」| eventsdf [,'type'] ==「輸入鏈接」)' 和運行時間 '用戶系統已過期 918.43 2.34 950.02' – Gandalf

+0

感謝Gabor。你能把這個作爲一個單獨的答案,以便我可以接受嗎?另外,爲什麼這個速度比我使用的要快很多,有些解釋是很好的。 – Gandalf