解析数据文件中json对象的最佳方法

时间:2016-03-26 15:44:26

标签: python json regex

我正在尝试设置一个简单的数据文件格式,我正在使用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对象。 / p>

如果文件中只有一个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)

我想问题一直是:有更好的方法吗?更好的意思是更简单的代码,更灵活的代码,更强大的代码,还是真正的任何东西?

2 个答案:

答案 0 :(得分:1)

最简单的解决方案,正如克劳斯建议的那样,只是将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?),它已经具备了您在同一文件中存储数据和元数据方面所需的功能。

答案 1 :(得分:0)

我会单独存储标题。它可以为多个数据文件使用相同的头文件

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