2015-11-17 2 views
9

Je souhaite importer des données XML OData du Bureau néerlandais des statistiques (CBS) dans notre base de données. En utilisant lxml et les pandas, j'ai pensé que cela devrait être direct. En utilisant OrderDict je veux préserver l'ordre des colonnes pour la lisibilité, mais je ne peux pas le faire correctement.pandas.DataFrame.from_dict ne pas préserver l'ordre en utilisant OrderedDict

from collections import OrderedDict 
from lxml import etree 
import requests 
import pandas as pd 


# CBS URLs 
base_url = 'http://opendata.cbs.nl/ODataFeed/odata' 
datasets = ['/37296ned', '/82245NED'] 

feed = requests.get(base_url + datasets[1] + '/TypedDataSet') 
root = etree.fromstring(feed.content) 

# all record entries start at tag m:properties, parse into data dict 
data = [] 
for record in root.iter('{{{}}}properties'.format(root.nsmap['m'])): 
    row = OrderedDict() 
    for element in record: 
     row[element.tag.split('}')[1]] = element.text 
    data.append(row) 

df = pd.DataFrame.from_dict(data) 
df.columns 

data Contrôle, le OrderDict est dans le bon ordre. Mais en regardant df.head() les colonnes ont été triées par ordre alphabétique avec CAPS en premier?

Aidez quelqu'un?

Répondre

17

Quelque chose dans votre exemple semble être incohérent, comme data est un list et pas dict, mais en supposant que vous avez vraiment un OrderedDict:

Essayez de spécifier explicitement votre commande de colonne lorsque vous créez votre dataframe:

# ... all your data collection 
df = pd.DataFrame(data, columns=data.keys()) 

Cela devrait vous donner à votre dataframe avec les colonnes commandées juste la façon dont ils sont exacts dans le OrderedDict (via la liste générée data.keys())

+5

merci @ chris-sc, cela fonctionne. Le 'data' est une liste de OrderedDicts, donc en fait chaque élément de cette liste est un enregistrement. Légère modification de votre solution 'df = pd.DataFrame (data, columns = data [0] .keys())'. Pourtant, un peu décevant qu'il n'en déduise pas automatiquement, mais cela peut être juste moi ... – dkapitan

+0

Vous pouvez également aller avec le plus concis 'columns = data' depuis itération sur' data' itère sur les touches. –