可写入的是使用" Nullable {Type}(数据)"而不只是朱莉娅的数据

时间:2017-01-30 02:52:04

标签: dataframe export 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)时,我会在文本文件中收到以下类型的数字输出。

  

"可空{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

1 个答案:

答案 0 :(得分: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)。

如果你不喜欢这样,那么你最好还是写自己的"可写的"功能;它不是那么困难,它只是打开一个文件并打印你想要的每列的情况。

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

可空类型有两个字段:

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,因此实际上为空(尽管您可以查询{{ 1}}如果你真的想)。

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

.hasvalue=false