Python Pandas 数据框到 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31260151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Pandas Dataframe to XML
提问by Clint
would appreciate some assistance or push in the right direction. I have a pandas dataframe, from a txt file, and would like to insert it in an xml doc I'm making. I can set up the xml doc, and convert my dataframe to xml using: How do convert a pandas/dataframe to XML?But I just can't seem to insert the converted dataframe xml into the xml doc made.
希望得到一些帮助或朝着正确的方向努力。我有一个来自 txt 文件的 Pandas 数据框,并且想将它插入到我正在制作的 xml 文档中。我可以设置 xml 文档,并使用以下方法将我的数据帧转换为 xml:如何将Pandas/数据帧转换为 XML?但我似乎无法将转换后的数据框 xml 插入到制作的 xml 文档中。
So far, my code is:
到目前为止,我的代码是:
import pandas as pd
from xml.dom.minidom import Document
from xml.dom.minidom import parseString
colnamesRBR = ['TIMESTAMP','A']
df = pd.read_table('test_data.txt',sep = ',',header=0,names=colnamesRBR,parse_dates={'datetime':['TIMESTAMP']},index_col='datetime')
doc = Document()
base = doc.createElement('Timeseries')
doc.appendChild(base)
entry = doc.createElement('Series')
base.appendChild(entry)
entry1 = doc.createElement('Header')
entry.appendChild(entry1)
type = doc.createElement('type')
type_content = doc.createTextNode('instantaneous')
type.appendChild(type_content)
entry1.appendChild(type)
timeStepElem = doc.createElement('timeStep')
timeStepElem.setAttribute ('unit','minute')
timeStepElem.setAttribute ('multiplier','5')
entry1.appendChild(timeStepElem)
startDateElem = doc.createElement('startDate')
startDateElem.setAttribute ('time','13:30:00')
startDateElem.setAttribute ('date','2015-06-24')
entry1.appendChild(startDateElem)
eventElem = doc.createElement('event')
eventElem.setAttribute ('time','endDate')
eventElem.setAttribute ('date','2015-06-25')
eventElem.setAttribute ('value','2015-06-25')
entry.appendChild(eventElem)
def to_xml(df, filename=None, mode='w'):
def row_to_xml(row):
xml = []
for i, col_name in enumerate(row.index):
xml.append(' <event date="{0}" time="{1}" value="{1}"/>'.format(col_name, row.iloc[i]))
return '\n'.join(xml)
res = '\n'.join(df.apply(row_to_xml, axis=0))
if filename is None:
return res
with open(filename, mode) as f:
f.write(res)
series = parseString(to_xml(df)).childNodes[0]
entry.appendChild(series)
pd.DataFrame.to_xml = to_xml
print df.to_xml()
f = open("test.xml","w")
doc.writexml(f, indent = " ", addindent=" ",newl="\n")
f.close()
The xml saved output file looks good:
xml 保存的输出文件看起来不错:
<?xml version="1.0" ?>
<Timeseries>
<Series>
<Header>
<type>instantaneous</type>
<timeStep multiplier="5" unit="minute"/>
<startDate date="2015-06-24" time="13:30:00"/>
</Header>
<event date="2015-06-25" time="endDate" value="2015-06-25"/>
</Series>
</Timeseries>
and the pandas dataframe converted xml is good:
和Pandas数据框转换的 xml 是好的:
<event date="2015-03-09 15:40:00" time="52.2885" value="52.2885"/>
<event date="2015-03-09 15:50:00" time="52.3277" value="52.3277"/>
<event date="2015-03-09 16:00:00" time="52.5045" value="52.5045"/>
<event date="2015-03-09 16:10:00" time="52.5702" value="52.5702"/>
<event date="2015-03-09 16:20:00" time="52.5608" value="52.5608"/>
I just can't seem to get the above inserted the xml doc, under the series element, where I have manually done one in the doc. Been trying for a while, and just can't seem get it into the element.attribute function, at this point starting to wonder if I shouldn't just parse the txt directly to xml, but I like the pd option for now.
我似乎无法将上面的 xml 文档插入到 series 元素下,我在文档中手动完成了一个。尝试了一段时间,似乎无法将其放入 element.attribute 函数中,此时开始怀疑我是否不应该将 txt 直接解析为 xml,但我现在喜欢 pd 选项。
Just some sample data if it helps:
如果有帮助,请提供一些示例数据:
TIMESTAMP,A
2015/03/09 15:40,52.2885
2015/03/09 15:50,52.3277
2015/03/09 16:00,52.5045
2015/03/09 16:10,52.5702
2015/03/09 16:20,52.5608
The error currently is:
目前的错误是:
File "<ipython-input-10-906277431901>", line 1, in <module>
runfile('C:/Users/clinton.chrystal/Documents/Python Scripts/Clint/Text_changes/from_data_to_xml_for SO.py', wdir='C:/Users/clinton.chrystal/Documents/Python Scripts/Clint/Text_changes')
File "C:\Anaconda\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 682, in runfile
execfile(filename, namespace)
File "C:\Anaconda\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 71, in execfile
exec(compile(scripttext, filename, 'exec'), glob, loc)
File "C:/Users/clinton.chrystal/Documents/Python Scripts/Clint/Text_changes/from_data_to_xml_for SO.py", line 60, in <module>
series = parseString(to_xml(df)).childNodes[0]
File "C:\Anaconda\lib\xml\dom\minidom.py", line 1928, in parseString
return expatbuilder.parseString(string)
File "C:\Anaconda\lib\xml\dom\expatbuilder.py", line 940, in parseString
return builder.parseString(string)
File "C:\Anaconda\lib\xml\dom\expatbuilder.py", line 223, in parseString
parser.Parse(string, True)
ExpatError: junk after document element: line 2, column 2
采纳答案by maxymoo
First of all get rid of the Seriestags in your to_xmlmethod:
首先摆脱方法中的Series标签to_xml:
def to_xml(df, filename=None, mode='w'):
def row_to_xml(row):
date = row.TIMESTAMP.split()[0]
time = row.TIMESTAMP.split()[1]
value = row.A
xml = '<event date="{0}" time="{1}" value="{2}"></event>'.format(date, time, value)
return xml
res = ' '.join(df.apply(row_to_xml, axis=1))
if filename is None:
return res
with open(filename, mode) as f:
f.write(res)
Then you can create your XML tree like this:
然后你可以像这样创建你的 XML 树:
*from xml.dom.minidom import parseString
doc = Document()
base = doc.createElement('Timeseries')
doc.appendChild(base)
series = parseString('<Series>' + to_xml(df) + '</Series>').childNodes[0]
base.appendChild(series)
base.appendChild(series)
header = doc.createElement('Header')
series.appendChild(header)
type = doc.createElement('type')
type_content = doc.createTextNode('instantaneous')
type.appendChild(type_content)
header.appendChild(type)
timeStepElem = doc.createElement('timeStep')
timeStepElem.setAttribute ('unit','minute')
timeStepElem.setAttribute ('multiplier','5')
header.appendChild(timeStepElem)
startDateElem = doc.createElement('startDate')
startDateElem.setAttribute ('time','13:30:00')
startDateElem.setAttribute ('date','2015-06-24')
header.appendChild(startDateElem)
print(doc.toprettyxml())*
Output:
输出:
<?xml version="1.0" ?>
<Timeseries>
<Series>
<event date="2015/03/09" time="15:40" value="52.2885"/>
<event date="2015/03/09" time="15:50" value="52.3277"/>
<event date="2015/03/09" time="16:00" value="52.5045"/>
<event date="2015/03/09" time="16:10" value="52.5702"/>
<event date="2015/03/09" time="16:20" value="52.5608"/>
<Header>
<type>instantaneous</type>
<timeStep multiplier="5" unit="minute"/>
<startDate date="2015-06-24" time="13:30:00"/>
</Header>
</Series>
</Timeseries>

