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)
例如,我有一个如下所示的 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)