python - 使用 pandas dataframe 中的 JSON 对象优化解析文件,其中某些行中可能缺少键

标签 python json performance pandas memory

我正在寻求优化下面的代码,该代码大约需要 5 秒,这对于只有 1000 行的文件来说太慢了。

我有一个大文件,其中每一行都包含有效的 JSON,每个 JSON 如下所示(实际数据要大得多且嵌套,因此我使用此 JSON 片段进行说明):

  {"location":{"town":"Rome","groupe":"Advanced",
    "school":{"SchoolGroupe":"TrowMet", "SchoolName":"VeronM"}},
    "id":"145",
    "Mother":{"MotherName":"Helen","MotherAge":"46"},"NGlobalNote":2,
    "Father":{"FatherName":"Peter","FatherAge":"51"},
    "Teacher":["MrCrock","MrDaniel"],"Field":"Marketing",
     "season":["summer","spring"]}

我需要解析此文件,以便从每个 JSON 中仅提取一些键值,以获得结果数据帧:

Groupe      Id   MotherName   FatherName
Advanced    56   Laure         James
Middle      11   Ann           Nicolas
Advanced    6    Helen         Franc

但是我在数据框中需要的一些键在某些 JSON 对象中丢失了,所以我应该验证该键是否存在,如果不存在,则用 Null 填充相应的值。我使用以下方法:

df = pd.DataFrame(columns=['group', 'id', 'Father', 'Mother'])
with open (path/to/file) as f:
    for chunk in f:
        jfile = json.loads(chunk)

        if 'groupe' in jfile['location']:
            groupe = jfile['location']['groupe']
        else:
            groupe=np.nan

        if 'id' in jfile:
            id = jfile['id']
        else:
            id = np.nan

        if 'MotherName' in jfile['Mother']:
            MotherName = jfile['Mother']['MotherName']
        else:
            MotherName = np.nan

        if 'FatherName' in jfile['Father']:
            FatherName = jfile['Father']['FatherName']
        else: 
            FatherName = np.nan

        df = df.append({"groupe":group, "id":id, "MotherName":MotherName, "FatherName":FatherName},
            ignore_index=True)

我需要将整个 1000 行文件的运行时间优化为 <= 2 秒。在 PERL 中,相同的解析函数需要不到 1 秒,但我需要在 Python 中实现它。

最佳答案

如果您可以在初始化期间一步构建数据帧,您将获得最佳性能。 DataFrame.from_record 获取一系列元组,您可以从一次读取一条记录的生成器提供这些元组序列。您可以使用 get 更快地解析数据,当未找到该项目时,它将提供默认参数。我创建了一个名为 dummy 的空 dict 来传递中间 get,以便您知道链接的 get 可以工作。

我创建了一个包含 1000 条记录的数据集,在我蹩脚的笔记本电脑上,时间从 18 秒缩短到 0.06 秒。那就相当不错了。

import numpy as np
import pandas as pd
import json
import time

def extract_data(data):
    """ convert 1 json dict to records for import"""
    dummy = {}
    jfile = json.loads(data.strip())
    return (
        jfile.get('location', dummy).get('groupe', np.nan), 
        jfile.get('id', np.nan),
        jfile.get('Mother', dummy).get('MotherName', np.nan),
        jfile.get('Father', dummy).get('FatherName', np.nan))

start = time.time()
df = pd.DataFrame.from_records(map(extract_data, open('file.json')),
    columns=['group', 'id', 'Father', 'Mother'])
print('New algorithm', time.time()-start)

#
# The original way
#

start= time.time()
df=pd.DataFrame(columns=['group', 'id', 'Father', 'Mother'])
with open ('file.json') as f:
      for chunk in f:
           jfile=json.loads(chunk)
           if 'groupe' in jfile['location']:
               groupe=jfile['location']['groupe']
           else:
               groupe=np.nan
           if 'id' in jfile:
                id=jfile['id']
           else:
                id=np.nan
           if 'MotherName' in jfile['Mother']:
                MotherName=jfile['Mother']['MotherName']
           else:
                MotherName=np.nan
           if 'FatherName' in jfile['Father']:
                FatherName=jfile['Father']['FatherName']
           else: 
                FatherName=np.nan
           df = df.append({"groupe":groupe,"id":id,"MotherName":MotherName,"FatherName":FatherName},
            ignore_index=True)
print('original', time.time()-start)

关于python - 使用 pandas dataframe 中的 JSON 对象优化解析文件,其中某些行中可能缺少键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35644650/

相关文章:

performance - 在非整数键上有效地实现记忆化

image - Jank Busting 大型流体图像

python - 如何最好地对 2D 点数据执行曲面积分?

python - 反转一个字符串,如果它只包含可镜像的字母

c# - 无法在 C# 中解析此 Json 字符串

javascript - 为什么这个$.getJSON请求会出错?

c++ - 为什么将 std::endl 与 ostringstream 一起使用会影响输出速度?

python - 使用全局包的 windows virtualenv

Python ftplib 被动连接配置错误

c# - mysql数据的C#创建Json文件