包含XML列和多个值的Pyspark数据框架:从中提取列

2024-05-18 23:44:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个pyspark数据框架,其中一列包含XML。一行中的每个XML如下所示,有些有2个条目,有些有3个条目,有些有4个条目:

单行条目的示例:

<?xml version="1.0" encoding="utf-8"?> <goals> <goal id="445" name="xxxy" sex="F" /> <goal id="2468" name="qwerzui" sex="F" /> <goal id="4334" name="foo" sex="M" /> <goal id="15" name="fooh" sex="F" /> </goals>

我需要解析目标id、姓名和性别的值,并从中创建列

由于XML可以有多个条目,因此很难从中生成固定数量的列。我的想法是为这些属性中的每一个创建一列(意味着向dataframe添加3列),然后列表在其中

在本例中,使用列展开pyspark数据框:

^{tb1}$

我正在考虑一个UDF,它遍历XML列并从中创建列。你怎么看,这样做有意义吗?也可以在以后进行分析。实际上,在列中包含列表并不常见

我通过以下途径进行了尝试:

import xml.etree.ElementTree as ET

root = ET.fromstring(string)

通过下面的内容,我可以访问其中的值,但是我无法将其放入适当的udf函数中以扩展pyspark数据帧

for child in root:
  print(child.tag, child.attrib)
  
for child in root:
  print(child.attrib['age'],child.attrib['sex']) 

不幸的是,stackoverflow的其他解决方案无法帮助我,因此我希望找到解决我问题的方法


Tags: 数据nameidchild列表条目rootxml
2条回答

下面的代码生成3个列表

import xml.etree.ElementTree as ET

XML = '''<?xml version="1.0" encoding="utf-8"?> <goals> <goal id="445" name="xxxy" sex="F" /> 
                                                        <goal id="2468" name="qwerzui" sex="F" /> <goal id="4334" name="foo" sex="M" /> 
                                                        <goal id="15" name="fooh" sex="F" /> 
                                                </goals>
'''
final = []
attributes = ['id', 'name', 'sex']
root = ET.fromstring(XML)
for attrib in attributes:
    final.append([g.attrib[attrib] for g in root.findall('goal')])
print(final)

输出

[['445', '2468', '4334', '15'], ['xxxy', 'qwerzui', 'foo', 'fooh'], ['F', 'F', 'M', 'F']]

使用xpath。不需要使用UDF,应该可以提供更好的性能

df2 = df.selectExpr(
    ["xpath(col, 'goals/goal/@%s') as %s" % (c,c) for c in ['id', 'name', 'sex']]
)

df2.show(20,0)
+          -+             +      +
|id                   |name                      |sex         |
+          -+             +      +
|[445, 2468, 4334, 15]|[xxxy, qwerzui, foo, fooh]|[F, F, M, F]|
+          -+             +      +

如果要将它们添加为新列,请执行以下操作

df2 = df.selectExpr('*',
    *["xpath(col, 'goals/goal/@%s') as %s" % (c,c) for c in ['id', 'name', 'sex']]
)

相关问题 更多 >

    热门问题