我在将 XML 文件导入 Pandas 时遇到问题,我需要从两个父节点获取数据。一个父节点 (AgentID
) 直接包含数据,另一个 (Sales
) 包含子节点 (Location
, Size
, Status
) 包含数据,如下所示。
test_xml = '''<TEST_XML>
<Sales>
<AgentID>0001</AgentID>
<Sale>
<Location>0</Location>
<Size>1000</Size>
<Status>Available</Status>
</Sale>
<Sale>
<Location>1</Location>
<Size>500</Size>
<Status>Unavailable</Status>
</Sale>
</Sales>
</TEST_XML>'''
当我尝试将其导入到 Pandas Dataframe 时,下面是我能够在 Sale
标签下获取数据的唯一方法。
import pandas as pd
df = pd.read_xml(test_xml, xpath='//Sale')
这给了我一个如下所示的数据框:
Location Size Status
0 0 1000 Available
1 1 500 Unavailable
我需要在 DataFrame 中包含 AgentID
标签,以获得以下内容,但我没有成功。为了清楚起见,下面给出了预期输出:
AgentID Location Size Status
0 0001 0 1000 Available
1 0001 1 500 Unavailable
是否有办法操作 xpath
参数以将数据包含在 AgentID
标记内,或者使用 Pandas 的 无法做到这一点read_xml
函数?我尝试传递像 xpath=['//AgentID', '//Sale']
这样的列表,但当然,它不起作用......
最佳答案
我认为仅使用 read_xml()
无法获得所需的输出;然而,通过稍微操纵它是可能的。本质上,这个想法是使用通用 xpath 从 xml 获取所有内容,选择所需的列,将 AgentID
列填充到对应于 Sale
列;然后删除多余的行。
df = pd.read_xml(io.StringIO(test_xml), xpath='//*', dtype=str)[['AgentID', 'Location', 'Size', 'Status']]
df['AgentID'] = df['AgentID'].ffill()
df = df.dropna(how='any').astype({'Location': int, 'Size': int}).reset_index(drop=True)
获取父节点的“更简单”解决方案(尽管与OP中的确切问题无关)是将XML转换为Python字典并使用pd.json_normalize
将其规范化为数据帧。这是可行的,因为可以在此处指定元字段(在本例中为 AgentID
)。不过,我们需要安装第三方库(xmltodict
)来实现第一步。
!pip install xmltodict
import xmltodict
df = (
pd.json_normalize(xmltodict.parse(test_xml)['TEST_XML']['Sales'],
record_path=['Sale'], meta=['AgentID'])
[['AgentID', 'Location', 'Size', 'Status']]
)
关于python - 使用 read_xml 将数据从两个 XML 父节点导入到 Pandas DataFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77580556/