将Pandas DataFrame和元数据保存为JSON格式

4

我需要将一个Pandas DataFrame和一些元数据保存为JSON格式的文件。(JSON格式是必需的。)

背景
A) 我可以使用 DataFrame.to_json()DataFrame.from_json() 成功地读取/写入我的相当大的Pandas Dataframe到JSON中。没有问题。

B) 我没有问题,可以使用 json.dump()/json.load() 将我的元数据(dict)保存到JSON中。


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

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)

看起来Pandas的JSON格式和Python的JSON库不兼容。
我的第一个想法是追寻一种方法修改C的df.to_dict()输出,使其适用于Python的JSON库,但我在脑海中一直听到“如果你在Python中做某件事感到困难,那么你可能正在错误地做这件事。”。
问题:向Pandas DataFrame添加元数据并将其存储为JSON格式文件的规范/推荐方法是什么?
Python 2.7.10 Pandas 0.17
编辑1: 在尝试Evan Wright的好答案时,我发现了问题的根源:Pandas(截至0.17)不喜欢将多索引DataFrame保存为JSON。 我创建的库可以保存我的(多索引)DataFrame,在调用DataFrame.to_json()之前安静地执行df.reset_index()。我的新代码没有这样做。因此,它是由于MultiIndex而出现问题。
教训:孩子们,即使是你自己的文档,也要阅读文档。
编辑2: 如果您需要在单个JSON对象中存储DataFrame和元数据,请参见我的下面的答案。
2个回答

6
你应该把数据分行输入即可。
撰写代码时:
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))

将内容写成两个独立的字符串,这是一种不错的技巧。 - JS.

3

在我的问题中,我错误地说明了我需要在文件中获取JSON。在那种情况下,Evan Wright的答案是我首选的解决方案。

在我的情况下,我实际上需要将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']

在这个阶段,你需要重新创建你的多级索引(如果适用)。

1
这个答案很棒!关于读取数据,看起来 pandas API 已经改变,目前应该使用 from_dict 而不是 as_dict - apawelek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接