【发布时间】:2015-03-20 14:46:50
【问题描述】:
总结
我创建了由pandas 对象(如DataFrames 和Panels 等)组成的数据对象。我希望将这些对象序列化为json,速度是首要考虑因素。
使用pandas.Panel 的示例
比如说我有一个这样的面板:
In [54]: panel = pandas.Panel(
numpy.random.randn(5, 100, 10),
items = ['a', 'b', 'c', 'd', 'e'],
major_axis = pandas.DatetimeIndex(start = '01/01/2000',
freq = 'b',
periods = 100
),
minor_axis = ['z', 'y', 'x', 'v', 'u', 't', 's', 'r', 'q', 'o']
)
In [64]: panel
Out[64]:
<class 'pandas.core.panel.Panel'>
Dimensions: 5 (items) x 100 (major_axis) x 10 (minor_axis)
Items axis: a to e
Major_axis axis: 2000-01-03 00:00:00 to 2000-05-19 00:00:00
Minor_axis axis: z to o
我想把这个panel 变成扁平的json
注意:我正在对更复杂的对象执行此操作,但循环键和为每个键生成 json 数据的整体逻辑是相同的
我可以像这样写一个又快又脏的panel_to_json()函数:
def panel_to_json(panel):
d = {'__type__' : 'panel'}
for item in panel.items:
tmp = panel.loc[item ,: , :].to_json()
d[item] = eval(tmp)
return json.dumps(d)
In [58]: tmp = panel_to_json(panel)
In [59]: tmp[:100]
Out[59]: '{"a": {"q": {"948931200000": -0.5586319118, "951955200000": 0.6820748888, "949363200000": -0.0153867'
这让我得到了正确的结果,问题是eval 的使用非常成本很高。例如,如果我删除 eval 并在此处处理由 panel_no_eval_to_json 函数产生的少量 \\:
def panel_no_eval_to_json(panel):
d = {'__type__' : 'panel'}
for item in panel.items:
d[item] = panel.loc[item ,: , :].to_json()
return json.dumps(d)
In [60]: tmp = panel_no_eval_to_json(panel)
In [61]: tmp[:100]
Out[61]: '{"a": "{\\"z\\":{\\"946857600000\\":1.0233515965,\\"946944000000\\":-1.1333560575,\\"947030400000\\":-0.0072'
速度差异很大,查看他们的%timeit 值!!:
In [62]: %timeit panel_no_eval_to_json(panel)
100 loops, best of 3: 3.55 ms per loop
In [63]: %timeit panel_to_json(panel)
10 loops, best of 3: 41.1 ms per loop
最终目标
所以我的最终目标是遍历Panel(或我的对象,具有不同的键/属性,其中许多是Panel 和DataFrames),并合并json通过调用 to_json() 创建的流到聚合的 json 流(这实际上是我的数据对象的扁平化数据表示),就像使用上面的 panel_to_json 函数执行的一样(witheval)。
我的主要目标是:
- 利用现有的
pandas to_json功能 - 利用加速和现有库(我可以编写自己的
json_stream_merger,但显然这已经完成了,对吧?)
【问题讨论】:
标签: python json serialization pandas concat