【问题标题】:optimal method to parse a json object in a datafile解析数据文件中的 json 对象的最佳方法
【发布时间】:2016-07-14 05:35:21
【问题描述】:

我正在尝试设置一个简单的数据文件格式,并且我正在 Python 中使用这些文件进行分析。格式基本上由标题信息组成,然后是数据。出于语法和未来可扩展性的原因,我想使用 JSON 对象作为标头信息。示例文件如下所示:

{
  "name": "my material",
  "sample-id": null,
  "description": "some material",
  "funit": "MHz",
  "filetype": "material_data"
}
18  6.269311533 0.128658208 0.962033017 0.566268827
18.10945274 6.268810641 0.128691962 0.961950095 0.565591807
18.21890547 6.268312637 0.128725463 0.961814928 0.564998228...

如果数据长度/结构始终相同,则不难解析。然而,它在我的脑海中提出了一个关于解析 JSON 对象的最灵活方法的问题,给定未知数量的行,未知数量的嵌套花括号,以及文件中可能有多个 JSON 对象。

如果文件中只有一个 JSON 对象,可以使用这个正则表达式:

with open(fname, 'r') as fp:
    fstring = fp.read()

json_string = re.search('{.*}', fstring, flags=re.S)

但是,如果有多个 JSON 字符串,并且我想抓取第一个,我需要使用这样的东西:

def grab_json(mystring):
    lbracket = 0
    rbracket = 0
    lbracket_pos = 0
    rbracket_pos = 0

    for i in range(len(mystring)):
        if mystring[i] == '{':
            lbracket = 1
            lbracket_pos = i
            break

    for i in range(lbracket_pos+1, len(mystring)):
        if mystring[i] == '}':
            rbracket += 1
            if rbracket == lbracket:
                rbracket_pos = i
                break
        elif mystring[i] == '{':
            lbracket += 1

    json_string = mystring[lbracket_pos : rbracket_pos + 1]
    return json_string, lbracket_pos, rbracket_pos

json_string, beg_pos, end_pos = grab_json(fstring)

我猜这个问题一如既往:有没有更好的方法来做到这一点?更好的意思是更简单的代码、更灵活的代码、更健壮的代码或其他任何东西?

【问题讨论】:

  • 对所有数据使用 JSON,每个文件一个 JSON 结构。

标签: python json regex


【解决方案1】:

正如 Klaus 所建议的,最简单的解决方案就是对整个文件使用 JSON。这让你的生活变得更简单,因为写作只是json.dump,而阅读只是json.load。

第二种解决方案是将元数据放在一个单独的文件中,这样可以保持读取和写入的简单性,但会牺牲每个数据集的多个文件。

第三种解决方案是,在将文件写入磁盘时,预先添加 JSON 数据的长度。所以写作可能看起来像:

metadata_json = json.dumps(metadata)
myfile.write('%d\n' % len(metadata_json))
myfile.write(metadata_json)
myfile.write(data)

然后阅读看起来像:

with open('myfile') as fd:
  len = fd.readline()
  metadata_json = fd.read(int(len))
  metadata = json.loads(metadata)
  data = fd.read()

第四个选项是采用现有的存储格式(可能是hdf?),它已经具有您正在寻找的在同一文件中存储数据和元数据的功能。

【讨论】:

  • 再想一想,将所有内容保存在同一个 JSON 中是有道理的,尽管作为解析问题,我仍然很好奇是否还有其他与此相关的答案。我问这个问题的部分原因是我想保留通过从 Excel 复制/粘贴来轻松手动创建文件的可能性,我的公司大量使用 Excel,并且在 JSON 之后有数据块使这很容易。下一个最佳解决方案是: "data": [ x, y1, y2, y3 ,y4, x, y1, y2 , y3, y4....] 虽然这需要在粘贴之前进行一些查找/替换。跨度>
【解决方案2】:

我会单独存储标题。它会让你有可能对多个数据文件使用相同的头文件

或者,您可能想看看Apache Parquet Format,尤其是如果您想使用Spark power处理分布式集群上的数据

【讨论】:

    猜你喜欢
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 2022-01-06
    • 2010-09-06
    相关资源
    最近更新 更多