【问题标题】:How to read record format json in Julia?如何在 Julia 中读取记录格式 json?
【发布时间】:2020-10-31 22:11:53
【问题描述】:

我可以读取一个 json 文件并使用下面的代码转换成数据帧。

df = open(jsontable, "normal.json") |> DataFrame

normal.json 如下所示,

{"col1":["thasin", "hello", "world"],"col2":[1,2,3],"col3":["abc", "def", "ghi" ]}

所以最终的 df 有,

3×3 DataFrame
│ Row │ col1   │ col2  │ col3   │
│     │ String │ Int64 │ String │
├─────┼────────┼───────┼────────┤
│ 1   │ thasin │ 1     │ abc    │
│ 2   │ hello  │ 2     │ def    │
│ 3   │ world  │ 3     │ ghi    │

但是,相同的代码不适用于record 格式的 json 文件。

格式是列表,如 {column -> value}, ... , {column -> value}

我的示例 json

{"billing_account_id":"0139A","credits":[],"invoice":{"month":"202003"},"cost_type":"regular"}
{"billing_account_id":"0139A","credits":[1.45],"invoice":{"month":"202003"},"cost_type":"regular"}
{"billing_account_id":"0139A","credits":[2.00, 3.56],"invoice":{"month":"202003"},"cost_type":"regular"}

预期输出:

  billing_account_id cost_type      credits              invoice
0             0139A   regular           []  {'month': '202003'}
1             0139A   regular       [1.45]  {'month': '202003'}
2             0139A   regular  [2.0, 3.56]  {'month': '202003'}

这可以在 python 中完成,如下所示,

data = []
for line in open("sample.json", 'r'):
    data.append(json.loads(line))
print(data)
df=pd.DataFrame(data)

如何在 Julia 中做到这一点?

【问题讨论】:

    标签: julia julia-dataframe


    【解决方案1】:

    请注意,您的文件不是有效的 JSON(其行是有效的 JSON,而不是整个文件)。

    你可以这样做:

    julia> using DataFrames, JSON3
    
    julia> df = JSON3.read.(eachline("sample.json")) |> DataFrame;
    
    julia> df.credits = Vector{Float64}.(df.credits);
    
    julia> df.invoice = Dict{Symbol,String}.(df.invoice);
    
    julia> df
    3×4 DataFrame
    │ Row │ billing_account_id │ credits                    │ invoice                │ cost_type │
    │     │ String             │ Array{Float64,1}           │ Dict{Symbol,String}    │ String    │
    ├─────┼────────────────────┼────────────────────────────┼────────────────────────┼───────────┤
    │ 1   │ 0139A              │ 0-element Array{Float64,1} │ Dict(:month=>"202003") │ regular   │
    │ 2   │ 0139A              │ [1.45]                     │ Dict(:month=>"202003") │ regular   │
    │ 3   │ 0139A              │ [2.0, 3.56]                │ Dict(:month=>"202003") │ regular   │
    

    :credits:invoice 列上的转换是为了使它们的类型易于使用(否则它们使用 JSON3.jl 内部定义的类型)。

    更高级的选项是通过使用 NamedTuple 类型指定行模式来一次性完成,例如:

    julia> df = JSON3.read.(eachline("sample.json"),
                            NamedTuple{(:billing_account_id, :credits, :invoice, :cost_type),Tuple{String,Vector{Float64},Dict{String,String},String}}) |>
                DataFrame
    3×4 DataFrame
    │ Row │ billing_account_id │ credits                    │ invoice                 │ cost_type │
    │     │ String             │ Array{Float64,1}           │ Dict{String,String}     │ String    │
    ├─────┼────────────────────┼────────────────────────────┼─────────────────────────┼───────────┤
    │ 1   │ 0139A              │ 0-element Array{Float64,1} │ Dict("month"=>"202003") │ regular   │
    │ 2   │ 0139A              │ [1.45]                     │ Dict("month"=>"202003") │ regular   │
    │ 3   │ 0139A              │ [2.0, 3.56]                │ Dict("month"=>"202003") │ regular   │
    

    【讨论】:

      【解决方案2】:

      与朱莉娅的答案无关,但在 python 中你可以做到 pd.read_json("sample.json", lines=True)

      【讨论】:

        猜你喜欢
        • 2017-12-22
        • 2017-09-04
        • 2016-01-06
        • 1970-01-01
        • 1970-01-01
        • 2022-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多