使用子节点解析 xml 并创建一个 Pandas 数据框
Parse xml with sub-nodes and create a Pandas dataframe
我有以下 xml 格式:
<?xml version="1.0" encoding="UTF-8"?>
<results>
<run>
<information>
<logfile>s.log</logfile>
<version>33</version>
<mach>1</mach>
<problemname>mm1</problemname>
<timestamp>20201218.165122.053486</timestamp>
</information>
<controls>
<item>VARS</item>
</controls>
<result>
<status>4</status>
<time>3</time>
<obj>1.0</obj>
<gap>0.15</gap>
</result>
</run>
</results>
我在阅读此 post 后有一个示例代码来解析此文件,但它 returns None。但是,我的问题是,是否有一种快速的方法可以创建一个数据框,该数据框包含来自值(即 VARS)和 4 列(即状态、时间、对象和间隙)的索引。
import pandas as pd
from xml.etree import ElementTree as et
root = (et.parse('test.xml').getroot()).getchildren()
tags = {"tags":[]}
for elem in root:
tag = {}
tag["status"] = elem.attrib['status']
tag["time"] = elem.attrib['time']
tag["obj"] = elem.attrib['obj']
tag["gap"] = elem.attrib['gap']
tags["tags"]. append(tag)
df_users = pd.DataFrame(tags["tags"])
df_users.head()
这是我正在寻找的输出:
status time obj gap
VARS 4 3 1.0 0.15
我认为您仍然需要循环遍历 etree 以使用 xml 提取点点滴滴。
import pandas as pd
from xml.etree import ElementTree as et
root = et.parse('test.xml').getroot()
results = []
for ele in eles.findall('run'):
# assumed each run contains only one control item
control = ele.find('controls').find('item').text
# extract each run result and save it in the results
for attr in list(ele.find('result')):
result = {}
result['control'] = control
result[attr.tag] = attr.text
results.append(result)
# at last, convert into dataframe and set control as index
results = pd.DataFrame(results)
results = results.set_index('control')
我们可以使用ElementTree
的findall
和find
方法来提取我们需要的元素(result
的子元素作为列,controls/item
作为索引):
pd.DataFrame({x.tag: x.text for x in et.findall('./run/result//')},
index = [et.find('./run/controls/item').text])
输出:
status time obj gap
VARS 4 3 1.0 0.15
请注意,status 不在 root 下,但您正试图在 root 下找到它。
status
在父 result
.
之下
您需要递归检查子项下的状态。
参考documentation。它详细介绍了带有示例的方法。 findall
正如其他人所建议的那样有用。
我有以下 xml 格式:
<?xml version="1.0" encoding="UTF-8"?>
<results>
<run>
<information>
<logfile>s.log</logfile>
<version>33</version>
<mach>1</mach>
<problemname>mm1</problemname>
<timestamp>20201218.165122.053486</timestamp>
</information>
<controls>
<item>VARS</item>
</controls>
<result>
<status>4</status>
<time>3</time>
<obj>1.0</obj>
<gap>0.15</gap>
</result>
</run>
</results>
我在阅读此 post
import pandas as pd
from xml.etree import ElementTree as et
root = (et.parse('test.xml').getroot()).getchildren()
tags = {"tags":[]}
for elem in root:
tag = {}
tag["status"] = elem.attrib['status']
tag["time"] = elem.attrib['time']
tag["obj"] = elem.attrib['obj']
tag["gap"] = elem.attrib['gap']
tags["tags"]. append(tag)
df_users = pd.DataFrame(tags["tags"])
df_users.head()
这是我正在寻找的输出:
status time obj gap
VARS 4 3 1.0 0.15
我认为您仍然需要循环遍历 etree 以使用 xml 提取点点滴滴。
import pandas as pd
from xml.etree import ElementTree as et
root = et.parse('test.xml').getroot()
results = []
for ele in eles.findall('run'):
# assumed each run contains only one control item
control = ele.find('controls').find('item').text
# extract each run result and save it in the results
for attr in list(ele.find('result')):
result = {}
result['control'] = control
result[attr.tag] = attr.text
results.append(result)
# at last, convert into dataframe and set control as index
results = pd.DataFrame(results)
results = results.set_index('control')
我们可以使用ElementTree
的findall
和find
方法来提取我们需要的元素(result
的子元素作为列,controls/item
作为索引):
pd.DataFrame({x.tag: x.text for x in et.findall('./run/result//')},
index = [et.find('./run/controls/item').text])
输出:
status time obj gap
VARS 4 3 1.0 0.15
请注意,status 不在 root 下,但您正试图在 root 下找到它。
status
在父 result
.
您需要递归检查子项下的状态。
参考documentation。它详细介绍了带有示例的方法。 findall
正如其他人所建议的那样有用。