我正在尝试设置一个简单的数据文件格式,我正在使用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)
我想问题一直是:有更好的方法吗?更好的意思是更简单的代码,更灵活的代码,更强大的代码,还是真正的任何东西?
答案 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处理分布式群集上的数据