Юлия DataFrame заменить или избежать генерации «пропавших без вести» - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть DataFrame, который содержит потери по годам, и я агрегирую его следующим образом

df = DataFrames.DataFrame(Year = Int64[], Loss = Float64[])

push!(df, (1, 15))
push!(df, (3, 30))
push!(df, (3, 23))
push!(df, (4, 45))

aal = by(df, :Year, AAL=:Loss=>sum)
tot_aal = join(DataFrame(Year = 1:5), aal, on = :Year, kind = :left)

Вот что я получаю:

Year      AAL
1        15.0
2     missing
3        53.0
4        45.0
5     missing

Что в порядке, но я не могу найти четкий способ предотвратить появление пропавших без вести, я был бы рад иметь только нули в пропущенных объединениях ...

Любые предложения о том, как сделать это лучше, также приветствуются:)

Большое спасибо

1 Ответ

1 голос
/ 17 апреля 2019

Вы также можете достичь желаемого, написав:

julia> sort!([aal; DataFrame(Year=setdiff(1:5, aal.Year), AAL=0.0)])
5×2 DataFrame
│ Row │ Year  │ AAL     │
│     │ Int64 │ Float64 │
├─────┼───────┼─────────┤
│ 1   │ 1     │ 15.0    │
│ 2   │ 2     │ 0.0     │
│ 3   │ 3     │ 53.0    │
│ 4   │ 4     │ 45.0    │
│ 5   │ 5     │ 0.0     │

или на месте:

julia> sort!(append!(aal, DataFrame(Year=setdiff(1:5, aal.Year), AAL=0.0)))
5×2 DataFrame
│ Row │ Year  │ AAL     │
│     │ Int64 │ Float64 │
├─────┼───────┼─────────┤
│ 1   │ 1     │ 15.0    │
│ 2   │ 2     │ 0.0     │
│ 3   │ 3     │ 53.0    │
│ 4   │ 4     │ 45.0    │
│ 5   │ 5     │ 0.0     │

Чтобы исправить tot_aal на месте после его создания, вы можете написать:

julia> replace!(tot_aal.AAL, missing=>0.0)
5-element Array{Union{Missing, Float64},1}:
 15.0
  0.0
 53.0
 45.0
  0.0

julia> tot_aal
5×2 DataFrame
│ Row │ Year  │ AAL      │
│     │ Int64 │ Float64⍰ │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 15.0     │
│ 2   │ 2     │ 0.0      │
│ 3   │ 3     │ 53.0     │
│ 4   │ 4     │ 45.0     │
│ 5   │ 5     │ 0.0      │

Это немного рискованно, потому что обычно aal может изначально содержать missing значения (и тогда вы замените все missing независимо от их происхождения). Поэтому вы можете написать что-то вроде:

julia> tot_aal = join(DataFrame(Year = 1:5), aal, on = :Year, kind = :left, indicator=:source)
5×3 DataFrame
│ Row │ Year  │ AAL      │ source       │
│     │ Int64 │ Float64⍰ │ Categorical… │
├─────┼───────┼──────────┼──────────────┤
│ 1   │ 1     │ 15.0     │ both         │
│ 2   │ 2     │ missing  │ left_only    │
│ 3   │ 3     │ 53.0     │ both         │
│ 4   │ 4     │ 45.0     │ both         │
│ 5   │ 5     │ missing  │ left_only    │

julia> tot_aal.AAL[tot_aal.source .== "left_only"] .= 0.0
2-element view(::Array{Union{Missing, Float64},1}, [2, 5]) with eltype Union{Missing, Float64}:
 0.0
 0.0

julia> tot_aal
5×3 DataFrame
│ Row │ Year  │ AAL      │ source       │
│     │ Int64 │ Float64⍰ │ Categorical… │
├─────┼───────┼──────────┼──────────────┤
│ 1   │ 1     │ 15.0     │ both         │
│ 2   │ 2     │ 0.0      │ left_only    │
│ 3   │ 3     │ 53.0     │ both         │
│ 4   │ 4     │ 45.0     │ both         │
│ 5   │ 5     │ 0.0      │ left_only    │

или замените последний шаг на что-то вроде:

julia> foreach(eachrow(tot_aal)) do row
           row.source == "left_only" && (row.AAL = 0.0)
       end

julia> tot_aal
5×3 DataFrame
│ Row │ Year  │ AAL      │ source       │
│     │ Int64 │ Float64⍰ │ Categorical… │
├─────┼───────┼──────────┼──────────────┤
│ 1   │ 1     │ 15.0     │ both         │
│ 2   │ 2     │ 0.0      │ left_only    │
│ 3   │ 3     │ 53.0     │ both         │
│ 4   │ 4     │ 45.0     │ both         │
│ 5   │ 5     │ 0.0      │ left_only    │
...