从 .txt 文件处理 JSON 并在 Julia 中转换为 DataFrame
Processing JSON from a .txt file and converting to a DataFrame in Julia
来自 Julia Discourse 的交叉发布,以防这里有人有任何线索。
我只是想深入了解为什么下面的代码返回的数据框只包含我的 json 文件的第一行。如果您想尝试使用我正在使用的文件,您可以从 Microsoft Open Academic Graph site 下载 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 object,因为我可以索引到结果 object 并看到很多 JSON objects:
enter image description here
我的第一个猜测可能是换行符 \n 导致了转义问题,并尝试使用 chomp 来摆脱它们,但无法让它工作。
无论如何 - 任何帮助将不胜感激!
我认为问题在于文件是 JSON Lines 格式,而 JSON3 库仅 returns 它找到的第一个有效 JSON 值除非另有说明,否则字符串的开头。
tl;博士
使用关键字参数 jsonlines=true
调用 JSON3.read
。
为什么?
默认情况下,JSON3 将传递给其 read
函数的字符串解释为单个“JSON 文本”,由 RFC 8259 section 1.3.2:
A JSON text is a serialized value....
(我强调使用不定单数冠词"a.") section 1.3.3中定义了一个"JSON值":
A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false, null, true.
具有多个 JSON 值的字符串在技术上是多个“JSON 文本。”由解析器决定你给它的字符串参数的哪一部分是 JSON 文本,并且 JSON3 的作者选择作为默认行为从字符串的开头解析到第一个有效 JSON 值的结尾。
为了让 JSON3 将字符串读取为多个 JSON 值,您必须为其提供关键字选项 jsonlines=true
,记录为:
jsonlines
: A Bool indicating that the json_str
contains newline delimited JSON strings, which will be read into a JSON3.Array
of the JSON values. See jsonlines for reference. [default false]
例子
以这个简单的字符串为例:
two_values = "3.14\n2.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 Lines 字符串的解析,让调用者将字符串正确拆分为需要:
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]
来自 Julia Discourse 的交叉发布,以防这里有人有任何线索。
我只是想深入了解为什么下面的代码返回的数据框只包含我的 json 文件的第一行。如果您想尝试使用我正在使用的文件,您可以从 Microsoft Open Academic Graph site 下载 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 object,因为我可以索引到结果 object 并看到很多 JSON objects:
enter image description here
我的第一个猜测可能是换行符 \n 导致了转义问题,并尝试使用 chomp 来摆脱它们,但无法让它工作。
无论如何 - 任何帮助将不胜感激!
我认为问题在于文件是 JSON Lines 格式,而 JSON3 库仅 returns 它找到的第一个有效 JSON 值除非另有说明,否则字符串的开头。
tl;博士
使用关键字参数 jsonlines=true
调用 JSON3.read
。
为什么?
默认情况下,JSON3 将传递给其 read
函数的字符串解释为单个“JSON 文本”,由 RFC 8259 section 1.3.2:
A JSON text is a serialized value....
(我强调使用不定单数冠词"a.") section 1.3.3中定义了一个"JSON值":
A JSON value MUST be an object, array, number, or string, or one of the following three literal names: false, null, true.
具有多个 JSON 值的字符串在技术上是多个“JSON 文本。”由解析器决定你给它的字符串参数的哪一部分是 JSON 文本,并且 JSON3 的作者选择作为默认行为从字符串的开头解析到第一个有效 JSON 值的结尾。
为了让 JSON3 将字符串读取为多个 JSON 值,您必须为其提供关键字选项 jsonlines=true
,记录为:
jsonlines
: A Bool indicating that thejson_str
contains newline delimited JSON strings, which will be read into aJSON3.Array
of the JSON values. See jsonlines for reference. [default false]
例子
以这个简单的字符串为例:
two_values = "3.14\n2.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 Lines 字符串的解析,让调用者将字符串正确拆分为需要:
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]