Memproses statistik ringkasan koleksi kosong

 – Beragampengetahuan
6 mins read

Memproses statistik ringkasan koleksi kosong – Beragampengetahuan

Oleh: Blog Bogumił Kamiński

Repost dari:

Saat merancang solusi untuk analisis data, seseorang sering menghadapi dilema
pilihan antara melakukan hal yang benar dan hal yang nyaman.

Kasus spesifik dari situasi seperti itu adalah menghitung statistik ringkasan dari
koleksi kosong Alasannya adalah bahwa statistik tersebut seringkali tidak akurat.
didefinisikan untuk data kosong (jadi Julia membuat kesalahan), tetapi ilmuwan data sebagai gantinya
ingin mendapatkan beberapa nilai bendera sebagai gantinya. Hari ini saya ingin membahas tipikal
kasus situasi seperti itu dan solusi yang mungkin.

Posting ditulis di bawah Julia 1.8.2 dan DataFrames.jl 1.4.4.

Dalam hal ini, situasinya paling tidak bermasalah. Apa yang biasanya Anda dapatkan?
yang Anda harapkan (yaitu nol atau salah satu rentang nilai yang Anda
sintetis):

julia> sum(Int[])
0

julia> prod(Float64[])
1.0

julia> sum(skipmissing(Union{Int, Missing}[missing, missing]))
0

julia> prod(skipmissing(Union{Float64, Missing}[missing, missing]))
1.0

Satu-satunya kasus yang penting adalah saat Anda ingin bekerja dengan drum
wadah tipe elemen terlalu lebar:

julia> sum([])
ERROR: MethodError: no method matching zero(::Type{Any})

Solusi standar, untuk keduanya sum dan prod dikurangi adalah untuk menyediakan a
nilai inisialisasi manual dalam hal ini:

julia> sum([], init=0)
0

julia> prod([], init=1.0)
1.0

Saat menghitung minimum dan maximum secara default Anda mendapatkan kesalahan saat kosong
koleksi:

julia> minimum(Int[])
ERROR: MethodError: reducing over an empty collection is not allowed;
consider supplying `init` to the reducer

Seperti yang Anda lihat, kami mendapatkan dan kesalahan diminta lewat init nilai untuk
menurun, sehingga situasinya kurang menguntungkan.

Memang, jika demikian init nilai secara logis dapat diteruskan, berikut adalah solusi yang bagus:

julia> minimum(Float64[], init=Inf)
Inf

julia> maximum(Int[], init=typemin(Int))
-9223372036854775808

atau misalnya jika kita tahu kita sedang bekerja dengan nilai-nilai yang harus berada dalam rentang tertentu kita bisa
menawarkan kisaran ini. Kasus umum adalah dengan probabilitas:

julia> minimum([], init=1.0)
1.0

julia> maximum([], init=0.0)
0.0

Namun, terkadang kita mungkin menginginkan nilai sinyal khusus. Pada kasus ini
Anda memiliki dua pilihan. Salah satunya untuk memeriksa apakah koleksinya kosong, yang lainnya adalah
untuk menangkap pengecualian:

julia> x = Int[]
Int64[]

julia> isempty(x) ? missing : minimum(x)
missing

julia> try
           minimum(x)
       catch e
           isa(e, MethodError) ? missing : rethrow(e)
       end
missing

Anda dapat membungkus kedua solusi dengan fungsi untuk kenyamanan, jika Anda menggunakannya
sering dalam kode Anda. Kelemahan mereka adalah mereka menambahkan sedikit perhitungan
atas. Itu isempty memeriksa dalam beberapa kasus bukan merupakan operasi O(1). Paling
kasus umum adalah skipmissing. Itu trycatch metode memperkenalkan biaya
penanganan pengecualian.

dalam kasus extrema fungsi, situasinya mirip dengan minimum dan
maximum. Satu-satunya perbedaan adalah Anda memberikan dua nilai untuk init jika kamu
ingin menggunakan metode ini. Berikut adalah contoh dengan asumsi kita sedang memproses data
itu kemungkinannya:

julia> extrema(Float64[], init=(1.0, 0.0))
(1.0, 0.0)

Perhatikan bahwa dalam hal ini minimum lebih besar dari maksimum, jadi kita bisa
segera lihat bahwa koleksi telah berlalu kosong.

Saat menghitung mean, varatau stdkita mendapatkan NaN saat bekerja dengan drum
mengumpulkan:

julia> using Statistics

julia> mean(Int[])
NaN

julia> var(Float64[])
NaN

julia> std(Float64[])
NaN

Ini sudah diduga, karena kita melakukan pembagian dengan nol dalam perhitungannya.
Juga, mirip dengan sum dan prodketika koleksi memiliki elemen yang terlalu luas
mengetik kami mendapatkan kesalahan:

julia> mean([])
ERROR: MethodError: no method matching zero(::Type{Any})

Jika kami tidak menyukai perilaku default ini dan ingin menangani koleksi kosong
dalam kasus khusus, memeriksa apakah wadah kosong adalah solusi standar:

julia> x = Float64[]
Float64[]

julia> isempty(x) ? missing : var(x)
missing

Komputasi kuantum, dan terutama rata-rata, adalah kasus yang paling tidak nyaman
untuk mereka kami selalu mendapatkan kesalahan dan tidak dapat digunakan init nilai-nilai (karena mereka tidak
pengurangan):

julia> median(Int[])
ERROR: ArgumentError: median of an empty array is undefined, Int64[]

julia> quantile(Float64[], 0.1)
ERROR: ArgumentError: empty data vector

Di sini, untuk saat ini, satu-satunya solusi adalah memeriksa apakah koleksinya kosong
atau menangkap pengecualian:

julia> x = Float64[]
Float64[]

julia> isempty(x) ? missing : median(x)
missing

julia> try
           quantile(x, 0.1)
       catch e
           isa(e, ArgumentError) ? missing : rethrow(e)
       end
missing

Posting saya hari ini dimaksudkan sebagai referensi cepat untuk pengguna Julia sesekali
mengalami masalah ini saat bekerja dengan data mereka. pengalaman saya adalah yang terbaik
Situasi umum semacam ini terkait dengan data yang hilang. Ini adalah sebuah contoh
kasus masalah:

julia> using DataFrames

julia> using Random

julia> Random.seed!(1234);

julia> df = DataFrame(id=rand(1:10^6, 10^6),
                      value=rand([1:10; missing], 10^6))
1000000×2 DataFrame
     Row │ id      value
         │ Int64   Int64?
─────────┼─────────────────
       1 │ 325977        4
       2 │ 549052        9
       3 │ 218587        9
       4 │ 894246        8
       5 │ 353112        1
       6 │ 394256       10
       7 │ 953125  missing
       8 │ 795547        5
       9 │ 494250        1
    ⋮    │   ⋮        ⋮
  999993 │ 967428        9
  999994 │ 557085        1
  999995 │ 353965        5
  999996 │ 590548       10
  999997 │ 657727        2
  999998 │ 928733        3
  999999 │ 884126  missing
 1000000 │ 587503        2
        999983 rows omitted

Saya bertujuan untuk membuat data dengan cara yang cukup banyak missing nilai:

julia> combine(groupby(df, :value), proprow)
11×2 DataFrame
 Row │ value    proprow
     │ Int64?   Float64
─────┼───────────────────
   1 │       1  0.091109
   2 │       2  0.091387
   3 │       3  0.091394
   4 │       4  0.090954
   5 │       5  0.090504
   6 │       6  0.091412
   7 │       7  0.090809
   8 │       8  0.090844
   9 │       9  0.090254
  10 │      10  0.090795
  11 │ missing  0.090538

Sekarang perhatikan bahwa beberapa grup hanya akan memiliki missing nilai (dalam output di bawah ini
kelompok dengan :id setara dengan 12 di baris 7 adalah kasus seperti itu):

julia> combine(groupby(df, :id),
               :value => (x -> mean(ismissing, x)) => :propmissing)
632166×2 DataFrame
    Row │ id       propmissing
        │ Int64    Float64
────────┼──────────────────────
      1 │       2     0.0
      2 │       3     0.25
      3 │       4     0.0
      4 │       6     0.0
      5 │       8     0.0
      6 │       9     0.333333
      7 │      12     1.0
      8 │      15     0.5
      9 │      16     0.0
   ⋮    │    ⋮          ⋮
 632159 │  999990     0.0
 632160 │  999991     0.0
 632161 │  999992     0.0
 632162 │  999993     0.0
 632163 │  999994     0.0
 632164 │  999996     0.0
 632165 │  999997     0.0
 632166 │ 1000000     0.0
            632149 rows omitted

Jika sekarang kami mencoba menghitung misalnya rata-rata untuk setiap grup sambil mengabaikan yang hilang
Kami gagal:

julia> combine(groupby(df, :id), :value => median∘skipmissing)
ERROR: ArgumentError: median of an empty array is undefined, Int64[]

Solusinya, seperti yang kita bahas di postingan ini adalah menangani case kosong
koleksi dengan cara khusus. Saya biasanya suka isempty uji.

Jadi pertama-tama tentukan fungsi pembantu:

julia> withempty(f, default) = x -> isempty(x) ? default : f(x)
withempty (generic function with 1 method)

dan sekarang kita dapat menulis:

julia> combine(groupby(df, :id),
               :value => withempty(median, missing)∘skipmissing)
632166×2 DataFrame
    Row │ id       value_function_skipmissing
        │ Int64    Union{Missing, Float64}
────────┼─────────────────────────────────────
      1 │       2                         3.5
      2 │       3                         5.0
      3 │       4                         8.0
      4 │       6                         4.0
      5 │       8                         1.0
      6 │       9                         9.0
      7 │      12                   missing
      8 │      15                         3.0
      9 │      16                         7.0
   ⋮    │    ⋮                 ⋮
 632159 │  999990                         4.0
 632160 │  999991                         3.0
 632161 │  999992                         8.0
 632162 │  999993                         2.0
 632163 │  999994                         7.0
 632164 │  999996                         4.0
 632165 │  999997                         7.0
 632166 │ 1000000                         7.0
                           632149 rows omitted

Seperti yang Anda lihat, kami dapatkan missing di baris 7 untuk grup dengan :id nilai sama dengan
12 seperti yang diharapkan.

Jika Anda memiliki pemikiran tentang pro dan kontra dari metode yang saya diskusikan
hari ini periksa masalah ini dan beri komentar di sana. Terima kasih!

Software Terbaru Saat Ini



Aplikasi yang sedang trend saat ini

object oriented programming, programming language, programming adalah, web programming, belajar programming, tournament software, software, software adalah, contoh software, apa itu software, pengertian software, aplikasi, aplikasi penghasil uang, aplikasi bokep, aplikasi video, programming

#Memproses #statistik #ringkasan #koleksi #kosong

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *