GIS奮闘記

現役GISエンジニアの技術紹介ブログ。主にPythonを使用。

スポンサーリンク

Python で CSV を XML に変換する方法

さて、本日は Python で CSV を XML に変換する方法について書いてみようと思います。自粛ムードが高まってきていてなかなか外出はできないかと思いますが、休日にコーディングをするチャンスでもありますね。自分ももっと勉強しなければならないので、これを機にコーディングする時間を増やせればと思います。

使用する CSV

前回エントリーで使用した prefectures.csv を使ってみようと思います。興味のある方はぜひ前回のエントリーを読んでみてください。

f:id:sanvarie:20200411121747p:plain

www.gis-py.com

出力する XML

以下のような形で XML を出力しようと思います。

<root>
    <date>
        <year>2020</year>
        <month>4</month>
        <day>11</day>
    </date>
    <prefecture>東京都</prefecture>
    <info>
        <cases>500</cases>
        <hospitalized>100</hospitalized>
        <released>200</released>
        <death>10</death>
    </info>
</root>

使用するライブラリ

Pandas と ElementTree を使用します。

実行環境

Windows10 64bit
Python 3.6.6

サンプルコード

prefectures.csv を XML に変換するサンプルです。

# -*- coding: utf-8 -*-
import pandas as pd
import xml.etree.ElementTree as et

def csv2xml():
    input_file = r"D:\data\csv\prefectures.csv"
    output_file = r"D:\data\csv\prefectures.xml"

    # CSV 読込
    df = pd.read_csv(input_file)

    # ルートを作成
    root = et.Element("root")
    for i, row in df.iterrows():

        # 公表年、公表月、公表日の要素を作成
        child_root_date = et.SubElement(root, "date")
        year = et.SubElement(child_root_date, 'year')
        month = et.SubElement(child_root_date, 'month')
        day = et.SubElement(child_root_date, 'day')

        # 都道府県の要素を作成
        child_root_prefecture = et.SubElement(root, "prefecture")

        # 患者数(2020年3月28日からは感染者数)、現在は入院等、退院者、志望者の要素を作成
        child_root_info = et.SubElement(root, "info")
        cases = et.SubElement(child_root_info, 'cases')
        hospitalized = et.SubElement(child_root_info, 'hospitalized')
        released = et.SubElement(child_root_info, 'released')
        death = et.SubElement(child_root_info, 'death')

        # 各要素に値をセットする
        for iCol, column in df.iteritems():

            if iCol == "公表年":
                year.text = str(row[iCol])
            elif iCol == "公表月":
                month.text = str(row[iCol])
            elif iCol == "公表日":
                day.text = str(row[iCol])
            elif iCol == "都道府県":
                child_root_prefecture.text = str(row[iCol])
            elif iCol == "患者数(2020年3月28日からは感染者数)":
                cases.text = str(row[iCol])
            elif iCol == "現在は入院等":
                hospitalized.text = str(row[iCol])
            elif iCol == "退院者":
                released.text = str(row[iCol])
            elif iCol == "死亡者":
                death.text = str(row[iCol])

    # XMLを出力
    et.ElementTree(root).write(output_file, encoding="utf-8")

if __name__ == '__main__':
    csv2xml()

結果

想定通りの形で XML が出力されました。

f:id:sanvarie:20200411132917p:plain

さいごに

最初は少してこずったのですが、それ以外は意外とすんなりできました。ただ、もっとスマートなやり方があるような気がしてなりません。まだまだ勉強不足ですね。CSV から XML に変換するということはそんなに頻繁に行うことではないと思いますが、もし興味がある場合はぜひ試してみてください。また、今回のケースに限らず Pandas と ElementTree はよく使うライブラリですので、Python を勉強している、もしくは、勉強したいという方は別のケースでもぜひ使ってみてください。本日は以上です。