Windows处理XML文件到熊猫数据框?

时间:2019-10-14 15:57:12

标签: python xml pandas dataframe

我想将以下Windows命令的结果转换为熊猫数据框。

在Windows计算机上使用此命令生成原始数据

  

wmic进程获取Caption,Processid,ParentProcessId,CommandLine,   CreationDate,KernelModeTime,UserModeTime,ThreadCount,HandleCount,   WorkingSetSize,PeakWorkingSetSize,VirtualSize,PeakVirtualSize,   PageFaults,PageFileUsage,PeakPageFileUsage,ReadOperationCount,   WriteOperationCount,OtherOperationCount / format:rawxml

具有以下代码

with f.open("RunningProcess.xml") as praw:

etree = et.parse(praw)
xroot = etree.getroot()
nprop = []

for property in xroot.iter("PROPERTY"):
    xnames = property.get("NAME")
    nprop.append(xnames)

npropf = pandas.DataFrame(index=nprop)
rprows = []
data = []
inner = {}

for child in xroot.iter("PROPERTY"):
    for gchild in child.iterfind('VALUE'):
        inner[gchild.tag] = gchild.text
    data.append(inner)
    rprows.append(pandas.DataFrame(data))
    data = []; inner = {}

finaldf = pandas.concat(rprows, sort=False).reset_index(drop=True)


finaldf.index = nprop


rpdfhtml = finaldf.to_html(index=True, header=True, border=1)

我得到这个结果

first 39 lines of output

我想

  • 使前20个索引行变为列(标题为 WriteOperationCount)
  • 将值列改为行。

像这个例子 first 9 columns of desired output

1 个答案:

答案 0 :(得分:1)

欢迎光临!这是一个有趣的问题。这不是完美的方法,但希望对您有帮助

我想避免硬编码感兴趣的任何列。

假设-此文件将具有可预测的字段名称模式。

我使用了xml.etree.ElementTree,我发现它是一个简单的库

import xml.etree.ElementTree as ET

引用xml文件

file = '/location/to/file/RunningProcess.xml'

创建扁平化的DataFrame。我个人认为,这比完全在xml中提取XML

首先创建一个扁平列表

tree = ET.parse(file)
root = tree.getroot()

ls_processes = []

for COMMAND in root.iter('COMMAND'):
    for RESULTS in COMMAND.iter('RESULTS'):
        for PROPERTY in RESULTS.iter('PROPERTY'):

            VALUE = PROPERTY.find('VALUE') 

            if VALUE is not None:
                print(PROPERTY.attrib['NAME'],'|',PROPERTY.attrib['TYPE'],'|', VALUE.text )
                ls_processes.append([PROPERTY.attrib['NAME'],PROPERTY.attrib['TYPE'], VALUE.text])
            else:
                print(PROPERTY.attrib['NAME'],'|',PROPERTY.attrib['TYPE'],'|', "NO VALUE")
                ls_processes.append([PROPERTY.attrib['NAME'],PROPERTY.attrib['TYPE'], 'NO VALUE'])

这将产生看起来像这样的东西

Caption | string | System Idle Process
CommandLine | string | NO VALUE
CreationDate | datetime | 20191002111400.978894+060
HandleCount | uint32 | 0
KernelModeTime | uint64 | 159488690156250
OtherOperationCount | uint64 | 0 

转换为数据框

df_processes = pd.DataFrame(ls_processes)

重命名列以使数据框更易于使用

df_processes.columns = ['data','type','value']

创建感兴趣的列的列表

ls_columns = ['Caption', 'ProcessId', 'ParentProcessId', 'CommandLine', 'CreationDate', 'KernelModeTime', 'UserModeTime', 'ThreadCount', 'HandleCount', 'WorkingSetSize', 'PeakWorkingSetSize', 'VirtualSize', 'PeakVirtualSize', 'PageFaults', 'PageFileUsage', 'PeakPageFileUsage', 'ReadOperationCount', 'WriteOperationCount', 'OtherOperationCount']

创建每个关注列的Dataframe列

ls_processes = []
for column in ls_columns:
    print(column)
    ls_row = []
    for index, row in df_processes.iterrows():
        if row['data'] == column: 
            ls_row.append(row['value'])

    df = pd.DataFrame(ls_row)
    ls_processes.append(df)

按列将数据框合并在一起

df_processes_flat = pd.concat(ls_processes, axis = 1 ) 

使用先前创建的列表添加列名

df_processes_flat.columns = ls_columns

您将获得一个看起来像这样的数据框

enter image description here

我想说这些步骤不是最优雅的方法,但是希望可以很清楚地知道发生了什么。