【Python】XMLファイルをPandasのDataFrameに変換する
APIを叩けばJSONでデータが返ってくる
最近は、そんなAPIが主流であると思いますが
まだまだ現役の古いAPIであるとXMLでデータが返ってくると思います。
今回はPythonでXMLデータを扱って
Pandasのデータフレーム形式に変換する方法について紹介します。
XMLデータをPandasのデータフレーム形式に変換する
入力するXMLデータ
今回扱うXMLのデータは以下のようなものです。
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<library>ンゴ図書館</library>
<book>
<title>金正日入門</title>
<authors>
<author>
<name>金正恩</name>
<age>38</age>
</author>
<author>
<name>ドナルド・トランプ</name>
<age>74</age>
</author>
</authors>
</book>
<book>
<title>人工無能入門</title>
<authors>
<author>
<name>あくのんご</name>
<age>16</age>
</author>
<author>
<name>山田太郎</name>
<age>46</age>
</author>
</authors>
</book>
</books>
ライブラリのインストール
今回はXMLデータの読み込みと変換にlxmlとxmljsonを用います。
pip install xmljson
pip install lxml
インストールするには上記のコマンドを実行してください。
pip install pandas
Pandasがインストールされていない場合は、上記のコマンドを実行してPandasをインストールしてください。
ライブラリの読み込み
始めにpandas、xmljson、lxmlをインポートします。
import pandas as pd
import xmljson
from lxml import etree
上記のコードでライブラリをインポートします。
XMLファイルの読み込みとdict型(辞書型)への変換
# xmlの読み込み
xml_tree = etree.parse('sample.xml')
# すべてのタグの取得
xml_root = xml_tree.getroot()
# xmlデータをdict型に変換
xml_dict = xmljson.yahoo.data(xml_root)
上記のようなコードでXMLファイルを読み込んでdict型へ変換します。
OrderedDict([('books', OrderedDict([('library', 'ンゴ図書館'), ('book', [OrderedDict([('title', '金正日入門'), ('authors', OrderedDict([('author', [OrderedDict([('name', '金正恩'), ('age', '38')]), OrderedDict([('name', 'ドナルド・トランプ'), ('age', '74')])])]))]), OrderedDict([('title', '人工無能入門'), ('authors', OrderedDict([('author', [OrderedDict([('name', 'あくのんご'), ('age', '16')]), OrderedDict([('name', '山田太郎'), ('age', '46')])])]))])])]))])
xml_dictの中身は上記のようになります。
これをループなどを使って必要なデータを取り出します。
データを取り出してリストへ格納
xmlデータを取り出してリストへ格納します。
# xmlデータから本の情報リストを抜き出す
xml_books = xml_dict['books']['book']
# 本の情報を入れるリスト
book_data = []
for xml_book in xml_books:
# 本の情報を格納する辞書
book = {'book_title': xml_book['title']}
# xmlから著者の情報リストを抜き出す
xml_authors = xml_book['authors']['author']
for i, xml_author in enumerate(xml_authors):
book['author_name_' + str(i+1)] = xml_author['name']
book['author_age_' + str(i+1)] = xml_author['age']
book_data.append(book)
上記のようなコードでループを回してゴニョゴニョしてデータを取り出します。
どのようなデータが格納してあるかによって書くコードは変わってきますが
今回のサンプルXMLであればこのようなコードでデータが取り出せます。
リストからデータフレームへ変換
先ほど作成したリストからPandasのデータフレームへ変換します。
# リストをデータフレームへ変換
df = pd.DataFrame(book_data)
上記のようなコードで変換します。
book_title | author_name_1 | author_age_1 | author_name_2 | author_age_2 |
金正日入門 | 金正恩 | 38 | ドナルド・トランプ | 74 |
人工無能入門 | あくのんご | 16 | 山田太郎 | 46 |
データフレームに変換すると上記のようなデータとして取り出せます。
コード全体
コードをまとめると下記のようなコードになります。
import pandas as pd
import xmljson
from lxml import etree
# xmlの読み込み
xml_tree = etree.parse('sample.xml')
# すべてのタグの取得
xml_root = xml_tree.getroot()
# xmlデータをdict型に変換
xml_dict = xmljson.yahoo.data(xml_root)
print(xml_dict)
# xmlデータから本の情報リストを抜き出す
xml_books = xml_dict['books']['book']
# 本の情報を入れるリスト
book_data = []
for xml_book in xml_books:
# 本の情報を格納する辞書
book = {'book_title': xml_book['title']}
# xmlから著者の情報リストを抜き出す
xml_authors = xml_book['authors']['author']
for i, xml_author in enumerate(xml_authors):
book['author_name_' + str(i+1)] = xml_author['name']
book['author_age_' + str(i+1)] = xml_author['age']
book_data.append(book)
# リストをデータフレームへ変換
df = pd.DataFrame(book_data)
これでXMLをデータフレームへ変換できます。