Преобразование сложного xml в фреймворк pandas

Есть целое большое количество из подобных вопросов к этому здесь, на Stackru. Прошу прощения, если это повторится, но я не думаю, что это так, и я пробовал методы, описанные в других ответах, и они не решили проблему.

Я пробовал несколько методов преобразования XML-данных в фреймворк pandas с использованием ряда пакетов (xmltodict, xmldataset, и Python ElementTree). Однако в имеющихся у меня xml-данных больше подмножеств, чем в любом из примеров / ответов, которые я видел, и эти методы не дают мне результатов, которые я ищу.

По соображениям конфиденциальности я не могу предоставить полный доступ к XML-файлу, но расскажу как можно подробнее. Я читаю XML-данные с URL-адреса на OrderedDict, используяxmltodict вот так

import requests 
import xmltodict
url = "myurl" 
response = requests.get(url)
data = xmltodict.parse(response.content)
data

Мои данные XML теперь выглядят как OrderedDict с несколькими подмножествами OrderedDicts.

OrderedDict([('weatherdata',
          OrderedDict([('@xml',
                        'http://url.com'),
                       ('@xsi:',
                        'http://url.com'),
                       ('@created', '2020-07-01T12:42:07Z'),
                       ('meta',
                        OrderedDict([('model',
                                      [OrderedDict([('@name', ''),
                                                    ('@termin',
                                                     '2020-07-01T06:00:00Z'),
                                                    ('@runended',
                                                     '2020-07-01T09:24:39Z'),
                                                    ('@nextrun',
                                                     '2020-07-01T16:00:00Z'),
                                                    ('@from',
                                                     '2020-07-01T13:00:00Z'),
                                                    ('@to',
                                                     '2020-07-03T12:00:00Z')]),
                                       OrderedDict([('@name',
                                                     'ec_n1280_1hr'),
                                                    ('@termin',
                                                     '2020-07-01T00:00:00Z'),
                                                    ('@runended',
                                                     '2020-07-01T09:24:38Z'),
                                                    ('@nextrun',
                                                     '2020-07-01T18:00:00Z'),
                                                    ('@from',
                                                     '2020-07-03T13:00:00Z'),
                                                    ('@to',
                                                     '2020-07-04T18:00:00Z')]),
                                       OrderedDict([('@name',
                                                     'ec_n1280_3hr'),
                                                    ('@termin',
                                                     '2020-07-01T00:00:00Z'),
                                                    ('@runended',
                                                     '2020-07-01T09:24:38Z'),
                                                    ('@nextrun',
                                                     '2020-07-01T18:00:00Z'),
                                                    ('@from',
                                                     '2020-07-04T21:00:00Z'),
                                                    ('@to',
                                                     '2020-07-07T00:00:00Z')]),
                                       OrderedDict([('@name',
                                                     'ec_n1280_6hr'),
                                                    ('@termin',
                                                     '2020-07-01T00:00:00Z'),
                                                    ('@runended',
                                                     '2020-07-01T09:24:39Z'),
                                                    ('@nextrun',
                                                     '2020-07-01T18:00:00Z'),
                                                    ('@from',
                                                     '2020-07-07T06:00:00Z'),
                                                    ('@to',
                                                     '2020-07-11T00:00:00Z')])])])),
                       ('product',
                        OrderedDict([('@class', 'pointData'),
                                     ('time',
                                      [OrderedDict([('@datatype',
                                                     'forecast'),
                                                    ('@from',
                                                     '2020-07-01T13:00:00Z'),
                                                    ('@to',
                                                     '2020-07-01T13:00:00Z'),
                                                    ('location',
                                                     OrderedDict([('@altitude',
                                                                   '10'),
                                                                  ('@latitude',
                                                                   '53'),
                                                                  ('@longitude',
                                                                   '-6'),
                                                                  ('temperature',
                                                                   OrderedDict([('@id',
                                                                                 'TTT'),
                                                                                ('@unit',
                                                                                 'celsius'),
                                                                                ('@value',
                                                                                 '14.1')])),
                                                                  ('windDirection',
                                                                   OrderedDict([('@id',
                                                                                 'dd'),
                                                                                ('@deg',
                                                                                 '275.6'),
                                                                                ('@name',
                                                                                 'W')])),
                                                                  ('windSpeed',
                                                                   OrderedDict([('@id',
                                                                                 'ff'),
                                                                                ('@mps',
                                                                                 '2.1'),
                                                                                ('@beaufort',
                                                                                 '2'),
                                                                                ('@name',
                                                                                 'Svak vind')])),
                                                                  ('globalRadiation',
                                                                   OrderedDict([('@value',
                                                                                 '67.9'),
                                                                                ('@unit',
                                                                                 'W/m^2')])),
                                                                  ('humidity',
                                                                   OrderedDict([('@value',
                                                                                 '94.8'),
                                                                                ('@unit',
                                                                                 'percent')])),
                                                                  ('pressure',
                                                                   OrderedDict([('@id',
                                                                                 'pr'),
                                                                                ('@unit',
                                                                                 'hPa'),
                                                                                ('@value',
                                                                                 '1004.7')])),
                                                                  ('cloudiness',
                                                                   OrderedDict([('@id',
                                                                                 'NN'),
                                                                                ('@percent',
                                                                                 '100.0')])),
                                                                  ('lowClouds',
                                                                   OrderedDict([('@id',
                                                                                 'LOW'),
                                                                                ('@percent',
                                                                                 '100.0')])),
                                                                  ('mediumClouds',
                                                                   OrderedDict([('@id',
                                                                                 'MEDIUM'),
                                                                                ('@percent',
                                                                                 '82.7')])),
                                                                  ('highClouds',
                                                                   OrderedDict([('@id',
                                                                                 'HIGH'),
                                                                                ('@percent',
                                                                                 '0.0')])),
                                                                  ('dewpointTemperature',
                                                                   OrderedDict([('@id',
                                                                                 'TD'),
                                                                                ('@unit',
                                                                                 'celsius'),
                                                                                ('@value',
                                                                                 '13.4')]))]))]),
                                       OrderedDict([('@datatype',
                                                     'forecast'),
                                                    ('@from',
                                                     '2020-07-01T12:00:00Z'),
                                                    ('@to',
                                                     '2020-07-01T13:00:00Z'),
                                                    ('location',
                                                     OrderedDict([('@altitude',
                                                                   '10'),
                                                                  ('@latitude',
                                                                   '53'),
                                                                  ('@longitude',
                                                                   '-6'),
                                                                  ('precipitation',
                                                                   OrderedDict([('@unit',
                                                                                 'mm'),
                                                                                ('@value',
                                                                                 '0.4'),
                                                                                ('@minvalue',
                                                                                 '0.2'),
                                                                                ('@maxvalue',
                                                                                 '1.0'),
                                                                                ('@probability',
                                                                                 '68.2')])),
                                                                  ('symbol',
                                                                   OrderedDict([('@id',
                                                                                 'LightRain'),
                                                                                ('@number',
                                                                                 '9')]))]))]),
                                       OrderedDict([('@datatype',
                                                     'forecast'),
                                                    ('@from',
                                                     '2020-07-01T14:00:00Z'),
                                                    ('@to',
                                                     '2020-07-01T14:00:00Z'),
                                                    ('location',
                                                     OrderedDict([('@altitude',
                                                                   '10'),
                                                                  ('@latitude',
                                                                   '53'),
                                                                  ('@longitude',
                                                                   '-6'),
                                                                  ('temperature',
                                                                   OrderedDict([('@id',
                                                                                 'TTT'),
                                                                                ('@unit',
                                                                                 'celsius'),
                                                                                ('@value',
                                                                                 '14.1')])),
                                                                  ('windDirection',
                                                                   OrderedDict([('@id',
                                                                                 'dd'),
                                                                                ('@deg',
                                                                                 '350.4'),
                                                                                ('@name',
                                                                                 'N')])),
                                                                  ('windSpeed',
                                                                   OrderedDict([('@id',
                                                                                 'ff'),
                                                                                ('@mps',
                                                                                 '2.8'),
                                                                                ('@beaufort',
                                                                                 '2'),
                                                                                ('@name',
                                                                                 'Svak vind')])),
                                                                  ('globalRadiation',
                                                                   OrderedDict([('@value',
                                                                                 '38.9'),
                                                                                ('@unit',
                                                                                 'W/m^2')])),
                                                                  ('humidity',
                                                                   OrderedDict([('@value',
                                                                                 '92.4'),
                                                                                ('@unit',
                                                                                 'percent')])),
                                                                  ('pressure',
                                                                   OrderedDict([('@id',
                                                                                 'pr'),
                                                                                ('@unit',
                                                                                 'hPa'),
                                                                                ('@value',
                                                                                 '1004.8')])),
                                                                  ('cloudiness',
                                                                   OrderedDict([('@id',
                                                                                 'NN'),
                                                                                ('@percent',
                                                                                 '100.0')])),
                                                                  ('lowClouds',
                                                                   OrderedDict([('@id',
                                                                                 'LOW'),
                                                                                ('@percent',
                                                                                 '100.0')])),
                                                                  ('mediumClouds',
                                                                   OrderedDict([('@id',
                                                                                 'MEDIUM'),
                                                                                ('@percent',
                                                                                 '64.8')])),
                                                                  ('highClouds',
                                                                   OrderedDict([('@id',
                                                                                 'HIGH'),
                                                                                ('@percent',
                                                                                 '0.0')])),
                                                                  ('dewpointTemperature',
                                                                   OrderedDict([('@id',
                                                                                 'TD'),
                                                                                ('@unit',
                                                                                 'celsius'),
                                                                                ('@value',
                                                                                 '13.0')]))]))]),
                                       OrderedDict([('@datatype',
                                                     'forecast'),
                                                    ('@from',
                                                     '2020-07-01T13:00:00Z'),
                                                    ('@to',
                                                     '2020-07-01T14:00:00Z'),
                                                    ('location',
                                                     OrderedDict([('@altitude',
                                                                   '10'),
                                                                  ('@latitude',
                                                                   '53'),
                                                                  ('@longitude',
                                                                   '-6'),
                                                                  ('precipitation',
                                                                   OrderedDict([('@unit',
                                                                                 'mm'),
                                                                                ('@value',
                                                                                 '0.3'),
                                                                                ('@minvalue',
                                                                                 '0.2'),
                                                                                ('@maxvalue',
                                                                                 '0.7'),
                                                                                ('@probability',
                                                                                 '59.3')])),
                                                                  ('symbol',
                                                                   OrderedDict([('@id',
                                                                                 'LightRain'),
                                                                                ('@number',
                                                                                 '9')]))]))]),

Это небольшой участок данных, там еще сотни строк. Данные имеют несколько слоев, которые я могу распечатать:

[elem.tag for elem in root.iter()]

['weatherdata',
 'meta',
 'model',
 'model',
 'model',
 'model',
 'product',
 'time',
 'location',
 'temperature',
 'windDirection',
 'windSpeed',
 'globalRadiation',
 'humidity',
 'pressure',
 'cloudiness',
 'lowClouds',
 'mediumClouds',
 'highClouds',
 'dewpointTemperature',
 'time',
 'location',
 'precipitation',
 'symbol']

Метод, который приблизил меня к тому, что я хочу, заключался в подмножестве фрейма данных следующим образом:

df = pd.DataFrame(data["weatherdata"]['product']["time"])
df.head()

который дает фрейм данных, отсортированный по метке времени, но переменная 'location' содержит несколько словарей с переменными среды.

Затем я могу извлечь их:

df = df['location'].apply(pd.Series)
df

Но у этого все еще есть словари в переменных среды, поэтому я думаю, что должен быть лучший способ сделать это. Переменные широты, долготы и высоты являются константами и не обязательно должны быть в данных, мне просто нужны переменные среды.

Я хочу создать фрейм данных для переменных окружения, в каждой строке которого указано время, когда было произведено наблюдение, которое, надеюсь, будет выглядеть примерно так:

Еще одна сложность заключается в том, что осадки представлены иначе, чем другие переменные окружающей среды, с отдельным временным шагом. Я бы хотел, чтобы это тоже было включено в DataFrame.

Возможно, я делаю это совершенно неправильно, и был бы очень признателен за любой совет или помощь о том, как решить эту проблему.

0 ответов

Другие вопросы по тегам