Pandas有pandas.io.json.json_normalize
方法可以压扁json。
我有一个包含每行json数据的源文件(通过长时间运行的流程传输到该文件)。我真的无法修改写入该文件的内容。这是JSON的一个人为的例子:
{"type": "bar", "aspect": {"Positive": 1, "Negative": 0.6}}
{"type": "bar", "aspect": {"Positive": 0.6, "Negative": 1.5}}
我可以通过传递pandas.read_json
参数来使用普通的lines=True
方法来阅读它。但是我希望它被展平,就好像通过json_normalize一样,因为它将它变成一个非常有用的形式,例如。
>>> json_normalize(json.loads('{"type": "bar", "aspect": {"Positive": 1, "Negative": 0.6}}'))
aspect.Negative aspect.Positive type
0 0.6 1 bar
如果我遍历源,规范化并追加,那将导致我添加的每一行的完整副本。这真的会伤害到性能。
答案 0 :(得分:6)
您可以使用read_json
+ DataFrame constructor
+ add_prefix
+ drop
+ join
:
df = pd.read_json('file.json', lines = True)
print (df)
aspect type
0 {'Negative': 0.6000000000000001, 'Positive': 1} bar
1 {'Negative': 1.5, 'Positive': 0.6000000000000001} bar
df = (pd.DataFrame(df['aspect'].values.tolist())
.add_prefix('aspect.')
.join(df.drop('aspect', 1)))
print (df)
aspect.Negative aspect.Positive type
0 0.6 1.0 bar
1 1.5 0.6 bar
或者每行调用json.loads
,最后一次使用json_normalize
:
df = json_normalize(pd.Series(open('file.json').readlines()).apply(json.loads))
print (df)
aspect.Negative aspect.Positive type
0 0.6 1.0 bar
1 1.5 0.6 bar
df = json_normalize([json.loads(x) for x in open('file.json').readlines()])
print (df)
aspect.Negative aspect.Positive type
0 0.6 1.0 bar
1 1.5 0.6 bar
5k行计时:
In [13]: %timeit json_normalize([json.loads(x) for x in open('file.json').readlines()])
10 loops, best of 3: 112 ms per loop
In [14]: %timeit json_normalize(pd.Series(open('file.json').readlines()).apply(json.loads))
10 loops, best of 3: 117 ms per loop
In [15]: %%timeit
...: df = pd.read_json('file.json', lines = True)
...: df = (pd.DataFrame(df['aspect'].values.tolist()).add_prefix('aspect.').join(df.drop('aspect', 1)))
...:
10 loops, best of 3: 30.1 ms per loop