@ciel_tktk

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Pythonで子と孫の数が異なるXMLからデータフレーム作成

解決したいこと

Pythonで子と孫の数が異なる場合のXMLを解析してデータフレームを作成したいです。

例)以下の様なXMLがある場合にNullを含めてデータを取得したいと考えています。

<?xml version="1.0"?>
<data>
    <country name="Japan">
		<Prefecture name = "Tokyo"> 
			<City name = "Shinagawa"/>
		</Prefecture>
		<Prefecture name = "Tokyo"> 
			<City name = "Shibuya"/>
		</Prefecture>
		<Prefecture name = "Tokyo"> 
			<City name = "Shinjuku"/>
		</Prefecture>
		<Prefecture name = "Tokyo"> 
		</Prefecture>
		<Prefecture name = "Kanagawa">
			<City name = "Yokohama"/>
		</Prefecture>
		<Prefecture name = "Kanagawa">
			<City name = "Kawasaki"/>
		</Prefecture>	
    </country>
</data>

こんなデータフレームになることを期待しているのですが、XMLの解析方法がわからず困っております。
image.png

自分で試したこと

PrefectureとCityを別々で取得することはできたのですが、数が異なるのでConcatもできず、もっとスマートな方法があるかと思うのですが、到底解決にはいたりませんでしたので、お力添えをいただきたく思います。

df_pref = pd.DataFrame()

for x in eroot.findall(".//Prefecture"):
    df_pref = pd.concat([df_pref,pd.DataFrame([x.attrib])])

df_city = pd.DataFrame()

for x in eroot.findall(".//City"):
    df_city = pd.concat([df_city,pd.DataFrame([x.attrib])])
0 likes

1Answer

こんな方法はいかがでしょう?

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

eroot = ET.parse('prefectures.xml').getroot()

prefectures = eroot.findall(".//Prefecture")
prefecture = [prefecture.get('name') for prefecture in prefectures]
city = [None if (city := prefecture.find('City')) is None else city.get('name')
        for prefecture in prefectures]
df = pd.DataFrame({'Prefecture': prefecture, 'City': city})
print(df)
実行結果
  Prefecture       City
0      Tokyo  Shinagawa
1      Tokyo    Shibuya
2      Tokyo   Shinjuku
3      Tokyo       None
4   Kanagawa   Yokohama
5   Kanagawa   Kawasaki
2Like

Comments

  1. @ciel_tktk

    Questioner

    ありがとうございます。すごく参考になりました。
    内包表記でこうやって表現することができるんですね。まだ勉強不足ですががんばります。

Your answer might help someone💌