Python:API 请求嵌套字典到具有日期时间索引值的数据框

Luc*_*a91 5 python api datetime dataframe pandas

我使用 get 函数在 python 上运行查询以从 API 获取每小时价格数据:

result = (requests.get(url_prices, headers=headers, params={'SpotKey':'1','Fields':'hours','FromDate':'2016-05-05','ToDate':'2016-12-05','Currency':'eur','SortType':'ascending'}).json())
Run Code Online (Sandbox Code Playgroud)

其中“SpotKey”标识我想要从 API 检索的项目,在此示例中“1”是每小时价格时间序列(其他参数不言自明)。

查询的结果是:

{'SpotKey': '1',
 'SpotName': 'APX',
 'Denomination': 'eur/mwh',
 'Elements': [{'Date': '2016-05-05T00:00:00.0000000',
   'TimeSpans': [{'TimeSpan': '00:00-01:00', 'Value': 23.69},
    {'TimeSpan': '01:00-02:00', 'Value': 21.86},
    {'TimeSpan': '02:00-03:00', 'Value': 21.26},
    {'TimeSpan': '03:00-04:00', 'Value': 20.26},
    {'TimeSpan': '04:00-05:00', 'Value': 19.79},
    {'TimeSpan': '05:00-06:00', 'Value': 19.79},
...
    {'TimeSpan': '19:00-20:00', 'Value': 57.52},
    {'TimeSpan': '20:00-21:00', 'Value': 49.4},
    {'TimeSpan': '21:00-22:00', 'Value': 42.23},
    {'TimeSpan': '22:00-23:00', 'Value': 34.99},
    {'TimeSpan': '23:00-24:00', 'Value': 33.51}]}]}
Run Code Online (Sandbox Code Playgroud)

其中“Elements”是包含时间序列的相关列表,结构为“Date”键和“TimeSpans”键的嵌套字典。

每个“TimeSpan”键都包含一天中每个小时的其他嵌套字典,其中“TimeSpan”键代表该小时,“Value”键代表价格。

我想将其转换为数据框,例如:

Datetime           eur/mwh
2016-05-05 00:00:00 23.69
2016-05-05 01:00:00 21.86
2016-05-05 02:00:00 21.26
2016-05-05 03:00:00 20.26
2016-05-05 04:00:00 19.79
... ...
2016-12-05 19:00:00 57.52
2016-12-05 20:00:00 49.40
2016-12-05 21:00:00 42.23
2016-12-05 22:00:00 34.99
2016-12-05 23:00:00 33.51
Run Code Online (Sandbox Code Playgroud)

目前我设法这样做:

df = pd.concat([pd.DataFrame(x) for x in result['Elements']])
df['Date'] = pd.to_datetime(df['Date'] + ' ' + [x['TimeSpan'][:5] for x in df['TimeSpans']], errors='coerce')
df[result['Denomination']] = [x['Value'] for x in df['TimeSpans']]
df = df.set_index(df['Date'], drop=True).drop(columns=['Date','TimeSpans'])
df = df[~df.index.isnull()]
Run Code Online (Sandbox Code Playgroud)

我这样做是因为夏令时将“TimeSpan”每小时值替换为“dts”字符串,从而在创建日期时间索引时出现 ParseDate 错误。由于我会非常频繁地请求数据,并且可能会请求不同的粒度(例如,每半小时),是否有更好/更快/标准的方法将如此多的嵌套字典塑造成具有我寻找的格式的数据帧,从而避免解析夏令时更改的日期错误?

提前谢谢你,干杯。

小智 4

你没有给出dts的例子,所以我无法验证。但原则上,对Dateas 时间戳和TimeSpanas 时间增量进行分析应该使您能够忽略粒度变化,并可能包含额外的“dts”解析。

def parse_time(x):
    if "dst" not in x:
        return x[:5]+":00"
    return f"{int(x[:2])+1}{x[2:5]}:00"  # TODO ACTUALLY PARSE, time overflow etc

df = pd.DataFrame(result['Elements']).set_index("Date")
d2 = df.TimeSpans.explode().apply(pd.Series)
d2['Datetime'] = pd.to_datetime(d2.index) + pd.to_timedelta(d2.TimeSpan.apply(parse_dt))
pd.DataFrame(d2.set_index(d2.Datetime).Value).rename(columns={"Value": "eur/mwh"})
Run Code Online (Sandbox Code Playgroud)

给出

在此输入图像描述