我有一个
.xml
文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<Act bind="a" >
<Key frame="32" value="1" />
<Key frame="62" value="8" />
<Key frame="106" value="14" />
</>
<Act bind="b" >
<Key frame="32" value="1" />
<Key frame="62" value="30" />
<Key frame="106" value="30" />
</>
<Act bind="c" >
<Key frame="28" value="81" />
<Key frame="58" value="78" />
<Key frame="102" value="78" />
</>
</>
如何编写将这些值保存在 excel 文件中的脚本,其中我有与 binds 一样多的列和与 frames 一样多的行。此外,帧按升序排序,如果绑定没有帧值,则插入 0。像下面这样的东西:
a b c
28 0 0 81
32 1 1 0
58 0 0 78
62 8 30 0
102 0 0 78
106 14 30 0
非常感谢任何帮助。
正如@GillesQuénot所说,这真的不是在SO上提问的方式,所以请下次尝试做得更好。
尽管如此,这是一项足够有趣的作业,所以我试图解决它。首先,问题中的 xml 格式不正确,所以我将它(见下文)修复为我认为应该的格式。
一旦我们超过了那个,它就变成了一个有点杂技的任务,需要使用 lxml、xpath、列表理解、f-strings 和几个 pandas 方法——但它是可行的。 [注意那些可能想知道的人 - FWIW,我尝试但未能使用
pandas.read_xml()
实现同样的事情]。
所以一起:
#your xml, fixed
source = """<?xml version="1.0" encoding="UTF-8"?>
<root>
<Act bind="a">
<Key frame="32" value="1" />
<Key frame="62" value="8" />
<Key frame="106" value="14" />
</Act>
<Act bind="b">
<Key frame="32" value="1" />
<Key frame="62" value="30" />
<Key frame="106" value="30" />
</Act>
<Act bind="c">
<Key frame="28" value="81" />
<Key frame="58" value="78" />
<Key frame="102" value="78" />
</Act>
</root>
"""
from lxml import etree
doc = etree.XML(source.encode())
#you need to convert to int so it can be properly sorted later:
frames = [int(frm) for frm in doc.xpath('//Key/@frame')]
#find the unique values and sort them
uni_frames = sorted(set(frames))
#start preparing your dataframe
rows, cols = [],[]
for act in doc.xpath('//Act'):
#get the column names
cols.append(act.xpath('./@bind')[0])
row = []
for frame in uni_frames:
#get the frame values
val = f'.//Key[@frame={frame}]/@value'
entry = act.xpath(val)[0] if act.xpath(val) else "0"
row.append(entry)
rows.append(row)
#now assemble the dataframe itself
df = pd.DataFrame(rows)
df = df.transpose()
#rename the columns
df.columns = cols
#finally, insert the first column
df.insert(loc = 0,
column = 'frame',
value = uni_frames)
df
输出:
frame a b c
0 28 0 0 81
1 32 1 1 0
2 58 0 0 78
3 62 8 30 0
4 102 0 0 78
5 106 14 30 0