2017-01-30 15 views
1

Например, у меня есть DataFrame, как показано ниже, назовем его df.Writetable экспортирует данные с помощью «Nullable {Type} (data)» вместо данных в Julia

╔═════╦══════╦══════╦══════╗ 
║ 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», ДФ) Я получаю следующий тип вывода для числовых данных в текстовом файле.

"Nullable {Float64} (0,66)"

вместо

0,66

Любые мысли о том, как получить writetable экспортировать только данные?

EDIT:

Я хотел бы отметить, что это происходит только после импорта данных с использованием пакета ReadStat. Можно ли преобразовать весь набор данных только в массив, который можно экспортировать правильно? Это может решить проблему.

EDIT # 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 
+0

Не знаете, как ReadStat меняет ситуацию, но вы можете попробовать получить свои столбцы и преобразовать их в обычные массивы с плавающей запятой: 'convert (Array {Float64}, df [: a])' и/или, возможно, воссоздать ваш DataFrame, используя эти нормальные массивы. Но да, если я просто создаю нормальный фреймворк с указанным выше содержимым и напишу его с помощью 'writetable', вывод кажется прекрасным. –

+0

Я думаю, что я обнаружил проблему. Поскольку ReadStat использует пакет Nullable Arrays, он заменяет значения Null на #NULL. Эти значения не могут быть преобразованы. Функция конвертера, вышедшая выше, работает до тех пор, пока я не получу столбцы, где существуют значения #NULL. Я посмотрю, смогу ли я найти способ заменить их чем-то, что можно преобразовать либо в значение, либо просто с NA. Я попробовал 'replace (af [338], # NULL, NA)' где 338 - это столбец, в котором сначала появляется '# NULL', но я не могу выполнить код из-за' # '. –

+0

ах, я вижу. '# NULL' предназначен только для визуального представления. Фактическое значение - 'Nullable {Float64}()'. Если вы выполните 'a = Nullable {Float64}()', вы увидите, что 'a.hasvalue' является ложным. В отличие от 'a = Nullable {Float64} (1.0)' где 'a.hasvalue' истинно, а' a.value' - '1.0'. Я недостаточно разбираюсь в массивах Nullable или Nullable, чтобы узнать, существует ли какой-либо конкретный метод, но должно быть очень просто использовать приведенное выше в понимании списка и заменить значения «null» (то есть, где 'hasvalue' является ложным) с идентификатором по вашему выбору, например NaN, чтобы вы могли написать таблицу. –

ответ

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) 

Обратите внимание, что для каждого столбца, если есть хотя бы один недостающий val ue, ваши номера будут также отображаться внутри кавычек из-за смешанного массива. Если вы хотите, чтобы все целые числа, вам нужно выбрать другое значение по умолчанию для «Отсутствует», чтобы обозначить ваши отсутствующие значения (например, -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 

Или вы можете использовать функцию «получить», чтобы получить значение Nullable. Если вы не определили альтернативу в случае нулевой, вы получаете 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) имеет .value 1, но это лишнее, как он объявлен как .hasvalue=false и поэтому эффективно null (хотя вы можете запросить .value, если вы действительно этого захотите).

обнуляемого экземпляр определяется как n = Nullable{Float64}() даст вам обнуляемого экземпляр с .hasvalue=false и бессмысленное значение, по-видимому, что было в памяти в этом месте во время создания экземпляра, хотя интерпретируется как любой тип Nullable вы объявили (т.е. Float64):

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

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

Ты гений. Я изменил способ, которым я немного это сделал, я использовал 'f (x) = [get (y, NA) для y в x];' вместо 'f (x) = [get (y," Missing ") для y в x]; '. Это позволяет мне использовать значения DataArrays.Ntype вместо преобразования их в строки. Одна вещь, которую я не понимаю, - это как работает функция f (x)? Я не понимаю, как он идентифицирует только значения #NULL и преобразовывает их в NA или «отсутствует». –

+0

Кроме того, я считаю: hasvalue был изменен на: isnull в v0.5 и выше. Когда я запускаю 'fieldnames (Nullable)' I get': isnull: value' –

+0

Я использую версию dev, так что это, вероятно, наоборот. (То есть isnull, вероятно, был изменен на hasvalue).Что касается предыдущего комментария, f (x) выполняет стандартное понимание списка; для каждого элемента в массиве с нулевыми значениями он «получает» значение элемента и заменяет любые значения NULL по умолчанию –

 Смежные вопросы

  • Нет связанных вопросов^_^