Estrategias de prueba del método pandas read_xml()

| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |

Actualmente, herramientas de E/S de pandas no mantiene un read_xml() y el método homólogo to_xml(). Sin embargo, read_json demuestra que se pueden implementar estructuras similares a árboles para la importación de marcos de datos y read_html para formatos de marcado.

Si el equipo de pandas considera tal método read_xml para una futura versión de pandas, ¿qué implementación harían? seguir: analizar con xml.etree.ElementTree incorporado con sus funciones iterfind() o iterparse() o el módulo de terceros, lxml con sus métodos XPath 1.0 y XSLT 1.0?

A continuación se muestran mis ejecuciones de prueba para cuatro tipos de métodos en una entrada XML simple, plana y centrada en elementos. Todos están configurados para el análisis generalizado de cualquier hijo de raíz de segundo nivel y cada método debe producir exactamente el mismo marco de datos de pandas. Todas excepto la última llamada pd.Dataframe() en la lista de diccionarios. El método XSLT transforma XML a CSV para convertir StringIO() en pd.read_csv().

Pregunta (varias partes)

  • RENDIMIENTO: ¿Cómo explica el iterparse más lento que a menudo se recomienda para archivos más grandes, ya que el archivo se analiza iterativamente? ¿Se debe en parte a las comprobaciones lógicas de if?

  • MEMORIA: ¿La memoria de la CPU se correlaciona con los tiempos en las llamadas de E/S? XSLT y XPath 1.0 tienden a no escalar bien con documentos XML más grandes, ya que se debe leer el archivo completo en la memoria para analizarlo.

  • ESTRATEGIA: ¿Es la lista de diccionarios una estrategia óptima para < código>Dataframe() llamada? Vea estas interesantes respuestas: generador versión y una versión iterwalk user-defined . Ambas listas actualizadas al marco de datos.

Input Data (Stack Overflow"s current principales usuarios por año de los cuales se incluyen nuestros amigos pandas)

<? xml version="1.0" encoding="utf-8"?> <stackoverflow> <topusers> <user>Gordon Linoff</user> <link>http://www.stackoverflow.com//users /1144035/gordon-linoff</link> <ubicación>Nueva York, Estados Unidos</ubicación> <year_rep>5,985</year_rep> <total_rep>499,408</total_rep> <tag1>sql</ tag1> <tag2>sql-server</tag2> <tag3>mysql</tag3> </topusers> <topusers> <user>G√ºnter Z√∂chbauer</user> <link> http://www.stackoverflow.com//users/217408/g%c3%bcnter-z%c3%b6chbauer</link> <ubicación>Linz, Austria</ubicación> <year_rep>5835</year_rep> ; <total_rep>154,4 39</repeticiones_totales> <etiqueta1>angular2</etiqueta1> <etiqueta2>mecanografiado</etiqueta2> <etiqueta3>javascript</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>jezrael</usuario> <enlace>http://www.stackoverflow.com//users/2901002/jezrael</enlace> <ubicación>Bratislava, Eslovaquia</ubicación> <año_rep>5740</año_rep> <total_rep>83,237</total_rep> <etiqueta1>pandas</etiqueta1> <etiqueta2>python</etiqueta2> <etiqueta3>marco de datos</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>VonC</usuario> <enlace>http://www.stackoverflow.com//users/6309/vonc</enlace> <ubicación>Francia</ubicación> <año_rep>5577</año_rep> <total_rep>651,397</total_rep> <etiqueta1>git</etiqueta1> <etiqueta2>github</etiqueta2> <tag3>docker</tag3> </los mejores usuarios> <usuarios principales> <usuario>Martijn Pieters</usuario> <enlace>http://www.stackoverflow.com//users/100297/martijn-pieters</enlace> <ubicación>Cambridge, Reino Unido</ubicación> <año_rep>5337</año_rep> <total_rep>525,176</total_rep> <etiqueta1>python</etiqueta1> <etiqueta2>python-3.x</etiqueta2> <etiqueta3>python-2.7</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>TJ Crowder</usuario> <enlace>http://www.stackoverflow.com//users/157247/tj-crowder</enlace> <ubicación>Reino Unido</ubicación> <año_rep>5258</año_rep> <total_rep>508,310</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>jquery</etiqueta2> <etiqueta3>java</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>akrun</usuario> <enlace>http://www.stackoverflow.com//users/3732271/akrun</enlace> <ubicación></ubicación> <año_rep>5188</año_rep> <total_rep>229,553</total_rep> <etiqueta1>r</etiqueta1> <etiqueta2>dplyr</etiqueta2> <etiqueta3>marco de datos</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Wiktor Stribi?ew</usuario> <enlace>http://www.stackoverflow.com//users/3832970/wiktor-stribi%c5%bcew</enlace> <ubicación>Varsovia, Polonia</ubicación> <año_rep>4948</año_rep> <total_rep>158,134</total_rep> <etiqueta1>expresión regular</etiqueta1> <etiqueta2>javascript</etiqueta2> <etiqueta3>c#</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Darin Dimitrov</usuario> <enlace>http://www.stackoverflow.com//users/29407/darin-dimitrov</enlace> <ubicación>Sofía, Bulgaria</ubicación> <año_rep>4936</año_rep> <total_rep>709,683</total_rep> <etiqueta1>c#</etiqueta1> <etiqueta2>asp.net-mvc</etiqueta2> <etiqueta3>asp.net-mvc-3</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Eric Duminil</usuario> <enlace>http://www.stackoverflow.com//users/6419007/eric-duminil</enlace> <ubicación></ubicación> <año_rep>4.854</año_rep> <total_rep>12,557</total_rep> <etiqueta1>rubí</etiqueta1> <etiqueta2>ruby-on-rails</tag2> <etiqueta3>matrices</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>alecxe</usuario> <enlace>http://www.stackoverflow.com//users/771848/alecxe</enlace> <ubicación>Nueva York, Estados Unidos</ubicación> <año_rep>4723</año_rep> <total_rep>233,368</total_rep> <etiqueta1>python</etiqueta1> <etiqueta2>selenio</etiqueta2> <tag3>transportador</tag3> </los mejores usuarios> <usuarios principales> <usuario>Jean-Franßois Fabre</usuario> <enlace>http://www.stackoverflow.com//users/6451573/jean-fran%c3%a7ois-fabre</enlace> <ubicación>Toulouse, Francia</ubicación> <año_rep>4526</año_rep> <total_rep>30,027</total_rep> <etiqueta1>python</etiqueta1> <etiqueta2>python-3.x</etiqueta2> <etiqueta3>python-2.7</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>piRSquared</usuario> <enlace>http://www.stackoverflow.com//users/2336654/pirsquared</enlace> <ubicación>Bellevue, WA, Estados Unidos</ubicación> <año_rep>4482</año_rep> <total_rep>41,183</total_rep> <etiqueta1>pandas</etiqueta1> <etiqueta2>python</etiqueta2> <etiqueta3>marco de datos</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>CommonsWare</usuario> <enlace>http://www.stackoverflow.com//users/115145/commonsware</enlace> <ubicación>¿Quién quiere saber?</ubicación> <año_rep>4475</año_rep> <total_rep>616,135</total_rep> <etiqueta1>android</etiqueta1> <etiqueta2>java</etiqueta2> <tag3>intención de Android</tag3> </los mejores usuarios> <usuarios principales> <usuario>Quentin</usuario> <enlace>http://www.stackoverflow.com//users/19068/quentin</enlace> <ubicación>Reino Unido</ubicación> <año_rep>4464</año_rep> <total_rep>509,365</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>html</etiqueta2> <etiqueta3>css</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Jon Skeet</usuario> <enlace>http://www.stackoverflow.com//users/22656/jon-skeet</enlace> <ubicación>Reading, Reino Unido</ubicación> <año_rep>4348</año_rep> <total_rep>921.690</total_rep> <etiqueta1>c#</etiqueta1> <etiqueta2>java</etiqueta2> <etiqueta3>.net</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Félix Kling</usuario> <enlace>http://www.stackoverflow.com//users/218196/felix-kling</enlace> <ubicación>Sunnyvale, CA</ubicación> <año_rep>4324</año_rep> <total_rep>411.535</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>jquery</etiqueta2> <tag3>asíncrono</tag3> </los mejores usuarios> <usuarios principales> <usuario>mate</usuario> <enlace>http://www.stackoverflow.com//users/341994/matt</enlace> <ubicación></ubicación> <año_rep>4313</año_rep> <total_rep>220,515</total_rep> <etiqueta1>deslizar</etiqueta1> <etiqueta2>ios</etiqueta2> <etiqueta3>códigox</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Psidom</usuario> <enlace>http://www.stackoverflow.com//users/4983450/psidom</enlace> <ubicación>Atlanta, GA, Estados Unidos</ubicación> <año_rep>4236</año_rep> <total_rep>36,950</total_rep> <etiqueta1>python</etiqueta1> <etiqueta2>pandas</etiqueta2> <etiqueta3>r</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Martin R</usuario> <enlace>http://www.stackoverflow.com//users/1187415/martin-r</enlace> <ubicación>Alemania</ubicación> <año_rep>4195</año_rep> <total_rep>269,380</total_rep> <etiqueta1>deslizar</etiqueta1> <etiqueta2>ios</etiqueta2> <etiqueta3>swift3</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Barmar</usuario> <enlace>http://www.stackoverflow.com//users/1491895/barmar</enlace> <ubicación>Arlington, MA</ubicación> <año_rep>4179</año_rep> <total_rep>289,989</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>php</etiqueta2> <etiqueta3>jquery</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Alexey Mezenin</usuario> <enlace>http://www.stackoverflow.com//users/1227923/alexey-mezenin</enlace> <ubicación>??????</ubicación> <año_rep>4142</año_rep> <total_rep>31,602</total_rep> <etiqueta1>laravel</etiqueta1> <etiqueta2>php</etiqueta2> <etiqueta3>laravel-5.3</tag3> </los mejores usuarios> <usuarios principales> <usuario>BalusC</usuario> <enlace>http://www.stackoverflow.com//users/157882/balusc</enlace> <ubicación>Ámsterdam, Países Bajos</ubicación> <año_rep>4.046</año_rep> <total_rep>703,046</total_rep> <etiqueta1>java</etiqueta1> <etiqueta2>jsf</etiqueta2> <etiqueta3>servlets</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>GurV</usuario> <enlace>http://www.stackoverflow.com//users/6348498/gurv</enlace> <ubicación></ubicación> <año_rep>4.016</año_rep> <total_rep>7932</total_rep> <etiqueta1>sql</etiqueta1> <etiqueta2>mysql</etiqueta2> <etiqueta3>servidor sql</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Nina Scholz</usuario> <enlace>http://www.stackoverflow.com//users/1447675/nina-scholz</enlace> <ubicación>Berlín, Alemania</ubicación> <año_rep>3950</año_rep> <total_rep>61,135</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>matrices</etiqueta2> <etiqueta3>objeto</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>JB Nizet</usuario> <enlace>http://www.stackoverflow.com//users/571407/jb-nizet</enlace> <ubicación>Saint-Etienne, Francia</ubicación> <año_rep>3923</año_rep> <total_rep>418,780</total_rep> <etiqueta1>java</etiqueta1> <etiqueta2>hibernación</etiqueta2> <etiqueta3>java-8</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Frank van Puffelen</usuario> <enlace>http://www.stackoverflow.com//users/209103/frank-van-puffelen</enlace> <ubicación>San Francisco, CA</ubicación> <año_rep>3920</año_rep> <total_rep>86,520</total_rep> <etiqueta1>base de fuego</etiqueta1> <etiqueta2>firebase-database</tag2> <etiqueta3>android</tag3> </los mejores usuarios> <usuarios principales> <usuario>dasblinkenlight</usuario> <enlace>http://www.stackoverflow.com//users/335858/dasblinkenlight</enlace> <ubicación>Estados Unidos</ubicación> <año_rep>3.886</año_rep> <total_rep>475.813</total_rep> <etiqueta1>c#</etiqueta1> <etiqueta2>java</etiqueta2> <etiqueta3>c++</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Tim Biegeleisen</usuario> <enlace>http://www.stackoverflow.com//users/1863229/tim-biegeleisen</enlace> <ubicación>Singapur</ubicación> <año_rep>3.814</año_rep> <total_rep>77,211</total_rep> <etiqueta1>sql</etiqueta1> <etiqueta2>mysql</etiqueta2> <etiqueta3>java</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Greg Hewgill</usuario> <enlace>http://www.stackoverflow.com//users/893/greg-hewgill</enlace> <ubicación>Christchurch, Nueva Zelanda</ubicación> <año_rep>3796</año_rep> <total_rep>529,137</total_rep> <etiqueta1>git</etiqueta1> <etiqueta2>python</etiqueta2> <etiqueta3>git-pull</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>unutbu</usuario> <enlace>http://www.stackoverflow.com//users/190597/unutbu</enlace> <ubicación></ubicación> <año_rep>3735</año_rep> <total_rep>401,595</total_rep> <etiqueta1>python</etiqueta1> <etiqueta2>pandas</etiqueta2> <etiqueta3>numpy</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Hans Passant</usuario> <enlace>http://www.stackoverflow.com//users/17034/hans-passant</enlace> <ubicación>Madison, WI</ubicación> <año_rep>3688</año_rep> <total_rep>672,118</total_rep> <etiqueta1>c#</etiqueta1> <etiqueta2>.net</etiqueta2> <tag3>formas ganadoras</tag3> </los mejores usuarios> <usuarios principales> <usuario>Jonathan Leffler</usuario> <enlace>http://www.stackoverflow.com//users/15168/jonathan-leffler</enlace> <ubicación>California, EE. UU.</ubicación> <año_rep>3649</año_rep> <total_rep>455,157</total_rep> <etiqueta1>c</etiqueta1> <etiqueta2>bash</etiqueta2> <etiqueta3>unix</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>paxdiablo</usuario> <enlace>http://www.stackoverflow.com//users/14860/paxdiablo</enlace> <ubicación></ubicación> <año_rep>3636</año_rep> <total_rep>507,043</total_rep> <etiqueta1>c</etiqueta1> <etiqueta2>c++</etiqueta2> <etiqueta3>bash</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Pranav C Balan</usuario> <enlace>http://www.stackoverflow.com//users/3037257/pranav-c-balan</enlace> <ubicación>Ramanthali, Kannur, Kerala, India</ubicación> <año_rep>3604</año_rep> <total_rep>64,476</total_rep> <etiqueta1>javascript</etiqueta1> <etiqueta2>jquery</etiqueta2> <etiqueta3>html</etiqueta3> </los mejores usuarios> <usuarios principales> <usuario>Suragch</usuario> <enlace>http://www.stackoverflow.com//users/3681880/suragch</enlace> <ubicación>Hohhot, China</ubicación> <año_rep>3580</año_rep> <total_rep>71,032</total_rep> <etiqueta1>deslizar</etiqueta1> <etiqueta2>ios</etiqueta2> <etiqueta3>android</tag3> </los mejores usuarios> </stackoverflow> 

Python Métodos

importar xml.etree.ElementTree como et importar pandas como pd desde io importar StringIO desde lxml importar etree as lxet def read_xml_iterfind(): árbol = et.parse("Input.xml") data = [] interior = {} for el in tree.iterfind("./*"): for i in el.iterfind("* "): interior[i.tag] = i.text data.append(interior) interior = {} df = pd.DataFrame(datos) def read_xml_iterparse(): datos = [] interior = {} i = 1 for (ev , el) en et.iterparse(ruta): if i <= 2: first_tag = el.tag if el.tag == first_tag and len(inner) != 0: data.append(inner) inner = {} if el.text no es Ninguno y len(el.text.strip()) > 0: interior[el.tag] = el.texto i += 1 df = pd.DataFrame(datos) def read_xml_lxml_xpath(): árbol = lxet.parse("Entrada.xml") datos = [] interior = {} for el in tree.xpath("/*/*"): for i in el: inner[i.tag] = i.text data.append(inner) inner = {} df = pd.DataFrame(data) def read_xml_lxml_xsl( ): xml = lxet.parse("Entrada.xml") xslstr = """ <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output version="1.0" codificación= "UTF-8" indent="yes" method="text"/> <xsl:strip-space elements="*"/> <!-- HEADERS --> <xsl:template match = "/*"> <xsl:for-each select="*[1]/*"> <xsl:value-of select="local-name()" /> <xsl:choose> <xsl:cuando prueba="posición() != último()"> <xsl:texto>,</xsl:texto> </xsl:cuando> <xsl:de lo contrario> <xsl: texto>&#xa;</xsl:texto> </xsl:de lo contrario> </xsl:elegir> </xsl:para-cada> <xsl:apply-templates/> </ xsl:template> <!-- FILAS DE DATOS (SEPARADAS POR COMA) --> <xsl:template match="/*/*"priority="2"> <xsl:for-each select=" *"> <xsl:if prueba="posición() = 1"> <xsl:texto>&quot;</xsl:texto> </xsl:if> <xsl:valor- de select="." /> <xsl:choose> <xsl:when test="position() != last()"> <xsl:text>&quot;,& quot;</xsl:texto> </xsl:cuando> <xsl:de lo contrario> <xsl:texto>&quot;&#xa;</xsl:texto> </xsl:de lo contrario> </xsl:elegir> </xsl:para-cada> </xsl:plantilla> </xsl:transformar> """ xsl = lxet.fromstring(xslstr) transform = lxet.XSLT(xsl) newdom = transform(xml) df = pd.read_csv(StringIO(str(newdom))) 

Tiempos (con XML actual y XML con 25 veces los hijos (es decir, 900 registros de usuario de StackOverflow)

# ARCHIVO CORTO python -mtimeit -s"importar readxml_test_runs como prueba" "test.read_xml_iterfind()" 100 bucles, al mejor de 3: 3,87 mseg por bucle python -mtimeit -s"importar readxml_test_runs como prueba" "test.read_xml_iterparse()" 100 bucles, al mejor de 3 : 5,5 mseg por bucle python -mtimeit -s"importar readxml_test_runs como prueba" "test.read_xml_lxml_xpath()" 100 bucles, lo mejor de 3: 3,86 mseg por bucle python -mtimeit -s"importar readxml_test_runs como prueba" "test.read_xml_lxml_xsl( )" 100 bucles, lo mejor de 3: 5,68 ms por bucle # ARCHIVO MÁS GRANDE python -mtimeit -n"100" -s"import readxml_test_runs as test" "test.read_xml_iterfind()" 100 bucles, lo mejor de 3: 36 ms por bucle python -mtimeit -n"100" -s"importar readxml_test_runs como prueba" "test.read_xml_i terparse()" 100 bucles, lo mejor de 3: 78,9 mseg por bucle python -mtimeit -n"100" -s"import readxml_test_runs as test" "test.read_xml_lxml_xpath()" 100 bucles, lo mejor de 3: 32,7 mseg por bucle python -mtimeit -n"100" -s"import readxml_test_runs as test" "test.read_xml_lxml_xsl()" 100 bucles, lo mejor de 3: 51,4 mseg por bucle