Writetable 正在使用 "Nullable{Type}(data)" 导出数据,而不仅仅是 Julia 中的数据

Writetable is exporting data with "Nullable{Type}(data)" instead of just data in Julia

例如,我有一个如下所示的 DataFrame,我们称它为 df。

╔═════╦══════╦══════╦══════╗
║ Row ║ a    ║ b    ║ c    ║
╠═════╬══════╬══════╬══════╣
║ 1   ║ 0.66 ║ 0.55 ║ 0.44 ║
╠═════╬══════╬══════╬══════╣
║ 2   ║ 0.11 ║ 0.22 ║ 0.33 ║
╠═════╬══════╬══════╬══════╣
║ 3   ║ 1.00 ║ 2.00 ║ 3.00 ║
╚═════╩══════╩══════╩══════╝

当我使用 writetable("output.txt",df) 时,我收到文本文件中数字数据的以下类型输出。

"Nullable{Float64}(0.66)"

而不是

0.66

有没有想过如何让可写表只导出数据?

编辑:

我应该注意,这只发生在使用 ReadStat 包导入数据之后。是否可以将整个数据集转换为可以正确导出的数组?这可能会解决问题。

编辑#2:

我刚刚尝试 运行 以下代码(利用创建的函数 converter),但收到错误消息(在下面发布)。

f(a,n)=
    if typeof(a[n])==NullableArrays.NullableArray{String,1}
    convert(Array{String},a[n])
elseif typeof(a[n])==NullableArrays.NullableArray{Float64,1}
    convert(Array{Float64},a[n])
elseif typeof(a[n])==NullableArrays.NullableArray{Int64,1}
    convert(Array{Float64},a[n])
end

converter(a)=hcat([f(a,n) for n=1:length(a)]...)

收到的错误如下:

julia> converter(af)
ERROR: NullException()
 in convert at /home/ale/.julia/v0.5/NullableArrays/src/primitives.jl:248 [inlined]
 in convert(::Type{Array{Float64,N}}, ::NullableArrays.NullableArray{Float64,1}) at /home/ale/.julia/v0.5/NullableArrays/src/primitives.jl:256
 in f(::DataFrames.DataFrame, ::Int64) at ./REPL[6]:5
 in collect_to!(::Array{Array{T,1},1}, ::Base.Generator{UnitRange{Int64},##1#2{DataFrames.DataFrame}}, ::Int64, ::Int64) at ./array.jl:340
 in collect_to!(::Array{Array{Float64,1},1}, ::Base.Generator{UnitRange{Int64},##1#2{DataFrames.DataFrame}}, ::Int64, ::Int64) at ./array.jl:350
 in collect(::Base.Generator{UnitRange{Int64},##1#2{DataFrames.DataFrame}}) at ./array.jl:308
 in converter(::DataFrames.DataFrame) at ./REPL[7]:1

看看/玩一下以下内容:

julia> using DataFrames
julia> a = [Nullable(0.1), Nullable{Float64}(), Nullable(0.3)];
julia> b = [Nullable{Float64}(), Nullable(2.), Nullable(3.)];
julia> df = DataFrame(Any[a,b], [:a,:b])
3×2 DataFrames.DataFrame
│ Row │ a     │ b     │
├─────┼───────┼───────┤
│ 1   │ 0.1   │ #NULL │
│ 2   │ #NULL │ 2.0   │
│ 3   │ 0.3   │ 3.0   │

julia> c = [df[x] for x in names(df)];
julia> f(x) = [get(y, "Missing") for y in x];
julia> d = Any[f(x) for x in c]; # "Any" required for dataframes (I think)
julia> df2 = DataFrame(d, names(df))
│ Row │ a         │ b         │
├─────┼───────────┼───────────┤
│ 1   │ 0.1       │ "Missing" │
│ 2   │ "Missing" │ 2.0       │
│ 3   │ 0.3       │ 3.0       │

julia> writetable("/home/tasos/Desktop/output.txt", df2)

请注意,对于每一列,即使有一个缺失值,由于混合数组,您的数字也会在引号内报告。如果你希望它全部是整数,你必须选择一个不同的默认值 "Missing" 来表示你的缺失值(例如 -1 如果你只期望正数)。

如果您不喜欢那样,那么您最好编写自己的 "writetable" 函数;这并不难,只是打开一个文件并按列打印你想要的内容。


此外,为了解决我们在评论中的一些讨论:

可空类型有两个字段:

julia> fieldnames(Nullable)
2-element Array{Symbol,1}:
 :hasvalue
 :value   

让我们创建两个实例来说明它们的含义:

julia> a = Nullable(1, true); b = Nullable(2, false);

julia> a.hasvalue, a.value
(true,1)

julia> b.hasvalue, b.value
(false,2)

您可以显式测试无效性:

julia> isnull(a)
false

julia> isnull(b)
true

julia> isnull(0), isnull("")
(false, false) # isnull returns false by default if input is not a Nullable Type

或者您可以使用 "get" 函数来获取 Nullable 的值。如果在 null 的情况下没有定义替代方案,则会得到 NullException:

julia> get(a)
1

julia> get(b)
ERROR: NullException()
Stacktrace:
 [1] get(::Nullable{Int64}) at ./nullable.jl:92

julia> get(b, "Null Detected")
"Null Detected"

定义为 Nullable(1, false) 的 Nullable 实例的 .value 为 1,但这是多余的,因为它被声明为 .hasvalue=false,因此实际上是空的(尽管您可以查询.value 如果你真的想要)。

定义为 n = Nullable{Float64}() 的可空实例将为您提供一个具有 .hasvalue=false 和无意义值的可空实例,可能是在实例化期间该位置内存中的任何内容,尽管被解释为可空类型您声明(即 Float64):

julia> n = Nullable{Float64}()
Nullable{Float64}()

julia> n.hasvalue, n.value
(false, 6.9015724352651e-310)