【问题标题】:Merge list of results into a single variable with Python使用 Python 将结果列表合并到单个变量中
【发布时间】:2021-06-01 19:06:23
【问题描述】:

我必须在 Python 中进行的开发包括获取一个带有从 sig 构建的树的 xml 文件。形状:

xml文件示例:I put here xml file becuase of big it is

上图中绿色的最后一个标签(Signal)是我必须从中提取Name和Value属性的值;这可以在这些属性中使用不同的值在同一级别重复两次或更多次。

读取 xml 的函数如下:

    import xml.etree.ElementTree as ET
    import pandas as pd
    
    file_xml = ET.parse('ejemplo.xml')
    print("File: ", rootXML)
    rootXML= file_xml.getroot()
    
    def fragmentXML(rootXML):
       for child1 in root:
          for child2 in child1:
             for child3 in child2:
                for child4 in child3:
                    for child5 in child4:
                       for child6 in child5:
                           for child7 in child6:
                               levelChild7(child7)

             transformData(values)

当使用 Pandas 获取数据时,将其放入数据框并对数据进行分组,我将它们一个一个分组,而不是一次全部分组;这是我用来对它们进行分组并使用 Matplotlib 将它们绘制在图表中的函数:

     def transformData(data_final):
        df_dataXML.groupby('Name')['Name'].count().plot(kind='bar')
        plot.show()

这是最后一个函数的控制台结果,它给我带来了单独的所有数据,显然还有图表:

问题是我不知道是否有任何方法可以加入 Signal 的属性(名称和值)以将它们传递给 Dataframe 中的 Pandas,我将所有内容与名称和值一起绘制在图表。而且我没有像上一张图​​片那样分别绘制每个名称和值。

我尝试过使用列表、元组和字典,但我无法将这些值合并,就好像标签是一个单独的实体,因此它是单独绘制的。

接下来我通过更改 levelChild7 和 transformData 函数与列表共享失败的尝试:

    def levelChild7(child):
       nameSignal = []
       valueSignal = []
       if child7.tag == 'chid7_e':
          for child8 in child7:
             for child9 in child8:
             print(child9.tag)
       elif child7.tag == 'chid7_f':
          for child8 in child7:
             for child9 in child8:
                print(child9.tag)
       elif child7.tag == 'chid7_p':
          for child8 in child7:
             for child9 in child8:
                print(child9.tag)
       else:
          for child8 in child7:
             nameSignal.append(Signal.attrib['Name'])
             prevValueSignal = Signal.attrib['Value']
             splitValueSignal = prevValueSignal.split(' ')
             valueSignal1st = splitValueSignal[0]
             valueSignal.append(int(valueSignal1st))
             values = nameSignal+valueSignal
             #print(values) 

             transformData(values)

    def transformData(data_final):
       df_dataXML = pd.DataFrame(data_final)
       print(df_dataXML)

结果如下,这是我无法找到如何分组的名称和值属性,因为它们由行和它在 XML 文档中找到的每个标记分隔:

谁能指导我知道如何重新组合Name和Values的值并将它们放在单个变量中?或者告诉我我的代码中缺少什么? 提前致谢。

【问题讨论】:

标签: python pandas xml dataframe matplotlib


【解决方案1】:

只需解析到所需的<Signal> 节点,这些节点可以在传递给pandas.DataFrame 构造函数的列表/字典理解中处理:

import xml.etree.ElementTree as ET
import pandas as pd

file_xml = ET.parse("Input.xml")

data = [
    {"Name": signal.attrib["Name"],
     "Value": signal.attrib["Value"]
    } for signal in file_xml.findall(".//Signal")
]

signals_df = pd.DataFrame(data)

signals_df
#            Name             Value
# 0        Status             4 Run
# 1   PhysicalRes       0 0,1 1,2 2
# 2        Status             4 Run
# 3        Status             1 Off
# 4     GlblClkYr    0 2000,21 2021
# 5        BrkTot        8191 Fault
# 6           ACU  0 FrontRequester
# 7           ACU           7 Radio
# 8           ACU  0 FrontRequester
# 9           ACU         4 Granted
# 10   GlblClkDay           1 1-3 3

signals_df.groupby(["Name"]).count()
#              Value
# Name
# ACU              4
# BrkTot           1
# GlblClkDay       1
# GlblClkYr        1
# PhysicalRes      1
# Status           3

如果您需要<Signal> 的所有属性,只需返回attrib 字典:

data = [signal.attrib for signal in file_xml.findall(".//Signal")]

signals_df = pd.DataFrame(data)

signals_df
#        Error    Hexval         Name             Value
# 0   {x:Null}     0,1,2       Status             4 Run
# 1   {x:Null}     0,1,2  PhysicalRes       0 0,1 1,2 2
# 2   {x:Null}      0,15       Status             4 Run
# 3   {x:Null}      0,15       Status             1 Off
# 4   {x:Null}      0,15    GlblClkYr    0 2000,21 2021
# 5   {x:Null}      1FFF       BrkTot        8191 Fault
# 6   {x:Null}  {x:Null}          ACU  0 FrontRequester
# 7   {x:Null}  {x:Null}          ACU           7 Radio
# 8   {x:Null}  {x:Null}          ACU  0 FrontRequester
# 9   {x:Null}  {x:Null}          ACU         4 Granted
# 10  {x:Null}         1   GlblClkDay           1 1-3 3

在即将发布的 Pandas v1.3 中,现在有一个针对 read_xml 的直接处理程序,默认情况下返回所有属性和子元素:

signals_df = pd.read_xml("Input.xml", xpath=".//Signal")

编译完所有数据后,根据需要运行绘图:

import xml.etree.ElementTree as ET
import pandas as pd
import matplotlib.pyplot as plt
...

signals_df.groupby(["Name"]).count().plot(kind='bar', rot=0)

plt.show()
plt.clf()
plt.close()

【讨论】:

  • 非常感谢@Parfait 的回答,它真的帮助我理解了我必须如何使用 ElementTree 的 findall() 方法......很高兴了解 Pandas v1.3 的版本,我还有1.1.5...你所有的解释对我帮助很大!!!...我的答案在下面...
  • 很高兴听到并乐于提供帮助!如果此解决方案对您最初发布的问题有所帮助,请考虑通过 accepting the helpful answer 将其关闭。如果您有其他问题,例如条形图而不是 XML 解析,请提出 new 问题。
  • 好的,谢谢...我发布了另一个与此相关的问题:stackoverflow.com/questions/67823936/…
猜你喜欢
  • 2022-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多