从.txt文件处理JSON并在Julia中转换为DataFrame

从Julia Discourse交叉发布,以防这里有人有任何线索。

我只是想了解为什么下面的代码返回一个只包含我的 json 文件第一行的数据帧。如果您想尝试使用我正在处理的文件,您可以从Microsoft Open Academic Graph 站点下载aminer_papers_0.zip ,我使用的是该组文件中的第一个文件。

using JSON3, DataFrames, CSV
file_name = "path/aminer_papers_0.txt"
json_string = read(file_name, String)
js = JSON3.read(json_string)
df = DataFrame([js])

生成的 DataFrame 只有一行,但列标题是正确的,第一行也是如此。对我来说,神秘的是为什么其余的没有得到处理。我想我可以排除 read() 只读取第一个 JSON 对象,因为我可以索引结果对象并看到许多 JSON 对象:

在此处输入图片说明

我的第一个猜测可能是换行符 n 导致了转义问题,并尝试使用 chomp 来摆脱它们,但无法使其正常工作。

无论如何 - 任何帮助将不胜感激!

回答

我认为问题在于文件是JSON Lines格式,除非另有说明,否则 JSON3 库只返回它在字符串开头找到的第一个有效 JSON 值。

tl;博士

调用JSON3.read与关键字参数jsonlines=true

为什么?

默认情况下,JSON3 将传递给其read函数的字符串解释为单个“JSON 文本”,由RFC 8259 第 1.3.2 节定义:

JSON 文本是一个序列化值....

(我强调使用不定单数冠词“a”。)“JSON 值”定义在 第 1.3.3 节:

JSON 值必须是对象、数组、数字或字符串,或以下三个字面名称之一:false、null、true。

其中包含多个 JSON 值的字符串在技术上是多个“JSON 文本”。由解析器决定您提供给它的字符串参数的哪一部分是 JSON 文本,JSON3 的作者选择作为默认行为从字符串的开头解析到第一个有效 JSON 值的结尾。

为了让 JSON3 将字符串读取为多个 JSON 值,您必须为其提供关键字 option jsonlines=true,其记录为:

jsonlines: Bool 表示json_str包含换行符分隔的 JSON 字符串,这些字符串将被读入JSON3.ArrayJSON 值中。请参阅jsonlines以供参考。[默认错误]

例子

以这个简单的字符串为例:

two_values = "3.14n2.72"

这些行中的每一行都是一个数字的有效 JSON 序列化。但是,当传递给 时JSON3.read,只会解析第一个:

using JSON3
@assert JSON3.read(two_values) == 3.14

使用jsonlines=true,两个值都被解析并作为JSON3.Array结构返回:

@assert JSON3.read(two_values, jsonlines=true) == [3.14, 2.72]

其他套餐

该JSON.jl库,里面的人可能会被命名为默认情况下使用,没有实现在所有的JSON字符串行的解析,留给了主叫方根据需要适当地分割字符串:

using JSON
JSON.parse(two_values)
# ERROR: Expected end of input
# Line: 1
# Around: ...3.14 2.72...
#                 ^

实现读取多个值的一种简单方法是使用eachline

@assert [JSON.parse(line) for line in eachline(IOBuffer(two_values))] == [3.14, 2.72]


以上是从.txt文件处理JSON并在Julia中转换为DataFrame的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>