如何将多个JSON文件读入Pandas数据框?

31

我正在尝试将多个以换行符分隔的JSON文件加载到单个Pandas数据帧中,但遇到了困难。这是我正在使用的代码:

import os, json
import pandas as pd
import numpy as np
import glob
pd.set_option('display.max_columns', None)

temp = pd.DataFrame()

path_to_json = '/Users/XXX/Desktop/Facebook Data/*' 

json_pattern = os.path.join(path_to_json,'*.json')
file_list = glob.glob(json_pattern)

for file in file_list:
    data = pd.read_json(file, lines=True)
    temp.append(data, ignore_index = True)

看起来通过查看file_list,所有的文件都已经加载了,但是我不能弄清楚如何将每个文件都放入dataframe中。大约有50个文件,每个文件中只有几行内容。

6个回答

37

将最后一行改为:

temp = temp.append(data, ignore_index = True)

我们需要这样做的原因是因为追加操作不会发生在原地。append方法不会修改数据帧,它只返回一个新的数据帧,其中包含追加操作的结果。
编辑:
自从我写下这个答案后,我了解到你永远不应该在循环内使用DataFrame.append,因为它会导致平方复制(参见这个答案)。
相反,你应该首先创建一个数据帧列表,然后使用pd.concat将它们全部连接成一个单一的操作。像这样:
dfs = [] # an empty list to store the data frames
for file in file_list:
    data = pd.read_json(file, lines=True) # read data frame from json file
    dfs.append(data) # append the data frame to the list

temp = pd.concat(dfs, ignore_index=True) # concatenate all the data frames in the list.

这个替代方案应该会更快。


7

如果需要将JSON展开,Juan Estevez的方法是行不通的。这里有一种替代方案:

import pandas as pd

dfs = []
for file in file_list:
    with open(file) as f:
        json_data = pd.json_normalize(json.loads(f.read()))
    dfs.append(json_data)
df = pd.concat(dfs, sort=False) # or sort=True depending on your needs

如果您的JSON采用了按行分隔的格式(未经测试):

import pandas as pd

dfs = []
for file in file_list:
    with open(file) as f:
        for line in f.readlines():
            json_data = pd.json_normalize(json.loads(line))
            dfs.append(json_data)
df = pd.concat(dfs, sort=False) # or sort=True depending on your needs

1
谢谢@ Skippy le Grand Gourou。我认为你的代码需要在'json_normalize'前加上'pd.'才能运行。 - BGG16

6
from pathlib import Path
import pandas as pd

paths = Path("/home/data").glob("*.json")
df = pd.DataFrame([pd.read_json(p, typ="series") for p in paths])

3

我结合了Juan Estevez的答案和glob。非常感谢。

import pandas as pd
import glob

def readFiles(path):
    files = glob.glob(path)
    dfs = [] # an empty list to store the data frames
    for file in files:
        data = pd.read_json(file, lines=True) # read data frame from json file
        dfs.append(data) # append the data frame to the list

    df = pd.concat(dfs, ignore_index=True) # concatenate all the data frames in the list.
    return df

0
这里还有另一个选择:
df = pd.DataFrame()  
for file in file_list:  
    data = pd.read_json(file, lines=True) 
    df = pd.concat([df,data], ignore_index=True)  

嗨AnnA,欢迎来到SO并感谢你的贡献。这个方法可以行得通,但正如接受的答案中的编辑部分所暗示的那样,在for循环内部以这种方式使用pd.concat是一个不好的主意,因为它会导致"二次复制"(来自链接的SO帖子)。首先创建一个dfs列表,如接受的答案中所示,然后仅在之后应用一次pd.concat将会显示出更好的性能。 - undefined

0
也许你应该说明一下,这些json文件是用pandas pd.to_json()自己创建的还是以其他方式创建的。 我使用的数据并不是通过pd.to_json()创建的,我认为在我的情况下无法使用pd.read_json()。相反,我编写了一个定制的for-each循环方法来将所有内容写入数据框中。

你可能的意思是“文件是否为有效的JSON格式”... ;) - Skippy le Grand Gourou

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