将数据帧和元数据保存为JSON格式

将数据帧和元数据保存为JSON格式,json,pandas,python-2.7,Json,Pandas,Python 2.7,我需要以JSON格式将Pandas数据帧以及一些元数据保存到文件中。(JSON格式是一项要求。) 背景 A)我可以使用Dataframe.to_JSON()和Dataframe.from_JSON()从JSON成功地读/写我的大熊猫数据帧。没问题 B)我使用JSON.dump()/JSON.load() 我的第一次尝试 由于Pandas不直接支持数据帧元数据,我的第一个想法是 top_level_dict = {} top_level_dict['data'] = df.to_dict() t

我需要以JSON格式将Pandas数据帧以及一些元数据保存到文件中。(JSON格式是一项要求。)

背景
A)我可以使用
Dataframe.to_JSON()
Dataframe.from_JSON()
从JSON成功地读/写我的大熊猫数据帧。没问题

B)我使用
JSON.dump()
/
JSON.load()


我的第一次尝试
由于Pandas不直接支持数据帧元数据,我的第一个想法是

top_level_dict = {}
top_level_dict['data'] = df.to_dict()
top_level_dict['metadata'] = {'some':'stuff'}
json.dump(top_level_dict, fp)

故障模式
C)我发现即使是

df_dict = df.to_dict()
json.dump(df_dict, fp)
在以下情况下失败:

TypeError: key (u'US', 112, 5, 80, 'wl') is not a string
D)调查后,我发现补码也失败了

df.to_json(fp)
json.load(fp)
失败于

384             raise ValueError("No JSON object could be decoded")
ValueError: Expecting : delimiter: line 1 column 17 (char 16)
因此,JSON格式和Python的JSON库似乎不兼容

我的第一个想法是寻找一种方法来修改C
df.to_dict()
输出,使其符合Python的JSON库,但我一直听到“如果你在用Python做一些事情,你可能做错了。”


问题
cannonical/推荐的向Pandas数据帧添加元数据并存储到JSON格式文件的方法是什么

Python 2.7.10
熊猫0.17

编辑1:
在尝试Evan Wright的伟大答案时,我发现了问题的根源:Pandas(从0.17开始)不喜欢将多索引数据帧保存到JSON。我为保存(多索引)数据帧而创建的库在调用
DataFrame.to\u json()
之前正在悄悄地执行
df.reset\u index()
。我的新代码不是。因此,它是
DataFrame.to_json()
在多索引上打嗝

教训:孩子们,即使是你自己的文档,也要阅读文档

编辑2:


如果需要在单个JSON对象中存储数据帧和元数据,请参见下面的回答。

您应该能够将数据放在单独的行中

写作:

f = open('test.json', 'w')
df.to_json(f)
print >> f
json.dump(metadata, f)
阅读:

f = open('test.json')
df = pd.read_json(next(f))
metdata = json.loads(next(f))

在我的问题中,我错误地说我需要一个文件中的JSON。在这种情况下,埃文·赖特的答案是我首选的解决方案

在我的例子中,我实际上需要将JSON输出作为一个“blob”存储在数据库中,因此我的字典争论方法似乎是必要的

如果您同样需要将数据和元数据存储在单个JSON blob中,则以下代码将起作用:

top_level_dict = {}
top_level_dict['data'] = df.to_dict()
top_level_dict['metadata'] = {'some':'stuff'}
with open(FILENAME, 'w') as outfile:
    json.dump(top_level_dict, outfile)
只需确保DataFrame是单独索引的。如果它是多索引的,请在执行上述操作之前重置索引(即
df.reset_index()

将数据读回:

with open(FILENAME, 'r') as infile:
    top_level_dict = json.load(infile)

df_as_dict = top_level_dict.pop('data', {})
df = pandas.DataFrame().as_dict(df_as_dict)

meta = top_level_dict['metadata']

此时,您需要重新创建多索引(如果适用)

在文件中作为两个单独的字符串写入。很好的技巧。这个答案很好!关于读回数据,看起来pandas API已经发生了变化,目前应该使用来自_dict的
,而不是像_dict
那样使用