快速将JSON列转换为Pandas数据框

27

我正在从一个数据库中读取数据(50k+ 行),其中一列存储为 JSON。我想将其提取到 pandas dataframe 中。 下面的片段可以正常工作,但效率相当低下,对整个数据库运行时需要很长时间。 请注意,并非所有项目都具有相同的属性,并且 JSON 具有一些嵌套属性。

如何使这个过程更快?

import pandas as pd
import json

df = pd.read_csv('http://pastebin.com/raw/7L86m9R2', \
                 header=None, index_col=0, names=['data'])

df.data.apply(json.loads) \
       .apply(pd.io.json.json_normalize)\
       .pipe(lambda x: pd.concat(x.values))
###this returns a dataframe where each JSON key is a column

3
df.data.apply(lambda x: pd.Series(json.loads(x))) 能否行得通? - Zero
你能否将粘贴的数据以不同(任何标准)格式存储? - MaxU - stand with Ukraine
@JohnGalt:可以工作,但这并没有将字典压平。 - jodoox
@MaxU:如果可能的话,我更愿意不改变抓取脚本。 - jodoox
3个回答

36

json_normalize 接受一个已经处理过的 JSON 字符串或者是一个包含这种字符串的 Pandas series。

pd.io.json.json_normalize(df.data.apply(json.loads))

设置

import pandas as pd
import json

df = pd.read_csv('http://pastebin.com/raw/7L86m9R2', \
                 header=None, index_col=0, names=['data'])

谢谢。这比你的第一个解决方案快得多 ;) - jodoox
1
我遇到了这个错误:'DataFrame'对象没有属性'data'。 - Ali Mirzaei
1
@AliMirzaei 请将其替换为您自己的列名。 - spicypumpkin
如果您的回答和Madhur Yadav的回答结合起来,包括一个示例,那就太好了。 - Jan Pisl

19

我认为你可以先将data字符串列转换为dict,然后通过values创建numpy数组list,最后使用DataFrame.from_records方法创建DataFrame:

df = pd.read_csv('http://pastebin.com/raw/7L86m9R2', \
                 header=None, index_col=0, names=['data'])

a = df.data.apply(json.loads).values.tolist() 
print (pd.DataFrame.from_records(a))

另一个想法:

 df = pd.json_normalize(df['data'])

谢谢 - 这比我的初始方法快了大约100倍。唯一的问题是它不会展开嵌套字典。这可能吗? - jodoox
抱歉,我不能翻译这个内容。 - jezrael
@jezrael 快问一下,你从变量'a'创建的csv和df的顺序是相同的,对吧?第一条记录将是第一条记录,第二条将是第二条,以此类推...它们会被打乱吗? - skybunk
1
@skybunk - 是的,完全正确。shuffle没有任何理由。 - jezrael

1
``` data = { "events":[ { "timemillis":1563467463580, "date":"18.7.2019", "time":"18:31:03,580", "name":"玩家正在加载", "data":"" }, { "timemillis":1563467463668, "date":"18.7.2019", "time":"18:31:03,668", "name":"玩家已加载", "data":"5" } ] } ```
from pandas.io.json import json_normalize
result = json_normalize(data,'events')
print(result)

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