Python/Pandas/XML将Pandas数据帧行写回LXML

2024-06-01 01:19:37 发布

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

我目前正在使用lxml接收一个XML文件,然后从根元素创建一个数据帧。我基本上在使用this example。我这样做是为了能够对数据进行一些数学/建模

我希望实现的下一步是能够将数据写回xml文档。在脚本的其他地方,我使用了root.insert,因为我可以强制在特定位置插入索引,以保持xml文档整洁一致

是否有一种方法可以为数据帧中的每一行使用类似root.insert(position, data)的东西写出数据帧的每一行,其中dataframes列标题是标记

示例XML

<Root_Data>

  <SomeData></SomeData>
  <SomeOtherData></SomeOtherData>   
   
  <Weather>
    <WxId>1</WxId>
    <Temp>20></WxId>
    <WindSpeed>15</WindSpeed>
  </Weather>

  # We will insert more weather here - I can find this position index. Assume it is 3.

  <SomeMoreData></SomeMoreData>
<Root_Data>

数据帧:

ID Temp Windspeed
2  25   30
3  30   15
4  15   25

我会提供一些迄今为止我已经尝试过的代码——但实际上,我已经空手而归地找到了如何将数据帧中的行插入到xml文档中,而不需要自己手动将xml构造为字符串(不是很好——标题可能会改变,这就是为什么我希望使用列标题作为标记的原因)

预期结果

<Root_Data>

  <SomeData></SomeData>
  <SomeOtherData></SomeOtherData>   
   
  <Weather>
    <WxId>1</WxId>
    <Temp>20></WxId>
    <WindSpeed>15</WindSpeed>
  </Weather>
  <Weather>
    <WxId>2</WxId>
    <Temp>25></WxId>
    <WindSpeed>30</WindSpeed>
  </Weather>
  <Weather>
    <WxId>3</WxId>
    <Temp>30></WxId>
    <WindSpeed>15</WindSpeed>
  </Weather>
  <Weather>
    <WxId>4</WxId>
    <Temp>15></WxId>
    <WindSpeed>25</WindSpeed>
  </Weather>

  <SomeMoreData></SomeMoreData>
<Root_Data>

到目前为止的示例代码:

from lxml import etree
import pandas as pd

tree = etree.parse('example.xml')
root = tree.getroot()

#Load into dataframe
for node in root:
            res=[]
            df_cols = ["WxId","Temp", "WindSpeed"]
            res.append(node.attrib.get(df_cols[0]))
            for el in df_cols[1:]:
                if node is not None and node.find(el) is not None:
                    res.append(node.find(el).text)
                else:
                    res.append(None)
            rows.append({df_cols[i]: res[i]
                        for i, _ in enumerate(df_cols)})
        out_df = pd.DataFrame(rows, columns = df_cols)
        out_df = out_df[~out_df['Temp'].isnull()] #Proxy for good / bad data. Remove nulls.

#Now, write from data frame back to root so we can structure the XML before writing to file. 
# ? Unknown method


Tags: 数据nodedfdataresrootxmltemp
2条回答

另一种方法,以防您的列未定义或将来可能增加

df = pd.read_csv('./123.csv')

root = etree.Element("root")
for rows in range(0,df.shape[0]):
    Tag = etree.Element('weather')
    for cols in range(0,df.shape[1]):
        etree.SubElement(Tag,df.iloc[rows:,cols].head().name).text = str(df.iloc[rows][cols])
    # Append Element "Tag" to the Main Root here
    root.append(Tag)

print(etree.tostring(root,encoding='Unicode'))

您可以使用to_xml将数据帧转换为xml:

xdata = df.rename(columns={'ID': 'WxId'})
          .to_xml(index=False, root_name='Root_Data', row_name='Weather')
>>> xdata
<?xml version='1.0' encoding='utf-8'?>
<Root_Data>
  <Weather>
    <WxId>2</WxId>
    <Temp>25</Temp>
    <Windspeed>30</Windspeed>
  </Weather>
  <Weather>
    <WxId>3</WxId>
    <Temp>30</Temp>
    <Windspeed>15</Windspeed>
  </Weather>
  <Weather>
    <WxId>4</WxId>
    <Temp>15</Temp>
    <Windspeed>25</Windspeed>
  </Weather>
</Root_Data>

现在,您可以使用lxml在第一个子Weather和最后一个子Weather之前插入数据,或者在原始xml文件中的某个位置插入扩展数据

FYI,您可以使用pd.read_xml将xml转换为数据帧

相关问题 更多 >