这里有一个large number中的similar questions,位于StackOverflow上。很抱歉,如果重复上述任何操作,但我不认为会重复,并且我尝试了其他答案中概述的方法,但尚未解决问题。
我尝试了多种方法,可以使用许多软件包(xmltodict
,xmldataset
和Python的ElementTree
)将xml数据转换为pandas数据帧。但是,我拥有的xml数据的子集比我看到的任何示例/答案都要多,并且这些方法无法提供我想要的结果。
出于隐私原因,我无法共享完整的xml文件,但是我会尽可能详细地提供信息。我正在像这样使用xmltodict
从url读取xml数据到OrderedDict
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中。
我可能完全以错误的方式进行了此操作,非常感谢您提供有关如何解决此问题的建议或帮助。