2017-08-21 16 views
2

この質問は、次の構造を効率的

私は、各項目がデータフレーム内のレコードになりたい
<items> 
<item> 
    <propertyA>1</propertyA> 
    <propertyB>B</propertyB> 
    <propertyC>2017</propertyC> 
</item> 
<item> 
    <propertyB>BB</propertyB> 
    <propertyD>D-2017</propertyD> 
</item> 
<item> 
    <propertyE>E</propertyE> 
    <propertyF>11:25</propertyF> 
</item> 
</items> 

で一貫性のないXMLを構文解析についてですパンダのデータフレームに一貫性のないXMLを解析します。最終データフレームには、すべてのプロパティA、B、C、D、E、Fが必要です。これらの値を持たない場合は、レコードにNaNなどが必要です。

私は今それをやっている方法は、あなたが確実に見ることができるように、私はデータフレームに新しいpd.Seriesを追加することによって、それをやっている

def load_inconsistent_xml(xml): 
root = ET.fromstring(xml) 
frames = [] 
df = pd.DataFrame() 
for child in root.iter('item'): 
    record = [] 
    headers = [] 
    for subchild in child: 
     headers.append(subchild.tag) 
     record.append(subchild.text) 

    s2 = pd.Series(record, index=headers) 
    df = df.append(s2, ignore_index=true) 

if not df.empty: 
    df.columns = df.columns.str.lower() 
return df 

です。このアプローチは(少なくとも私にとって:D)防弾であると思われ、私のデータは一貫しています。

問題は、あるそれは長い時間がかかり100kの項目で非常に非効率的です。 あなたは何をお勧めしますか?

ご質問ありがとうございました。私はPythonの初心者ですので、私はあなたの忍耐を感謝します。

答えて

0

pd.concat(高速の行/列バインダーメソッド)の系列の代わりにデータフレームを追加することを検討してください。これは、データフレームのリストの中の列がNANを満たしていない場合に発生します。また、データフレームに繰り返しキャストされた辞書のリストを使用して異なる構文解析を実行します。

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

xml_str = ''' 
<items> 
<item> 
    <propertyA>1</propertyA> 
    <propertyB>B</propertyB> 
    <propertyC>2017</propertyC> 
</item> 
<item> 
    <propertyB>BB</propertyB> 
    <propertyD>D-2017</propertyD> 
</item> 
<item> 
    <propertyE>E</propertyE> 
    <propertyF>11:25</propertyF> 
</item> 
</items>''' 

dfs = [] 

def load_inconsistent_xml(xml):   
    data = []; inner = {} 

    root = ET.fromstring(xml)   
    for child in root.iterfind('item'): 
     for grandchild in child.iterfind('./*'):    
      inner[grandchild.tag] = grandchild.text 

     data.append(inner) 
     dfs.append(pd.DataFrame(data)) 
     data = []; inner = {} 

    finaldf = pd.concat(dfs).reset_index(drop=True) 
    print(finaldf) 

# propertyA propertyB propertyC propertyD propertyE propertyF 
# 0   1   B  2017  NaN  NaN  NaN 
# 1  NaN  BB  NaN D-2017  NaN  NaN 
# 2  NaN  NaN  NaN  NaN   E  11:25