Tips dan trik broadcasting di DataFrames.jl – Beragampengetahuan
Oleh: Blog Bogumił Kamiński
Repost dari:
Penyiaran, alias . operator, adalah fitur canggih dari Julia yang memungkinkan Anda melakukannya
dengan mudah memvektorisasi fungsi apa pun. Hari ini saya ingin menulis tentang beberapa siaran populer
template dapat digunakan di DataFrames.jl.
Posting ditulis di bawah Julia 1.9.2 dan DataFrames.jl 1.5.0.
Mari kita buat kerangka data dengan beberapa hal acak:
julia> using DataFrames
julia> using Random
julia> df = DataFrame(rand(5, 6), :auto)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.690894 0.240867 0.720774 0.331573 0.549766
2 │ 0.225226 0.241412 0.0793279 0.418206 0.775367 0.35275
3 │ 0.19913 0.0633375 0.767805 0.280096 0.721995 0.917259
4 │ 0.708132 0.230088 0.702677 0.947402 0.928979 0.66101
5 │ 0.0267573 0.0122425 0.549734 0.331788 0.32658 0.00476749
Katakanlah kita ingin mendapatkan kerangka data baru true saat nilai disimpan
dalam kotak yang lebih besar 0.5 Dan false jika tidak. Ini mudah.
Kami baru saja mengudara > operator:
julia> df .> 0.5
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Bool Bool Bool Bool Bool Bool
─────┼──────────────────────────────────────────
1 │ false true false true false true
2 │ false false false false true false
3 │ false false true false true true
4 │ true false true true true true
5 │ false false true false false false
Sekarang misalkan kita ingin mengganti semua nilai lebih besar dari 0.5 dengan 0.5 Dan
menjaga nilai yang lebih rendah tidak berubah. Ini bisa dilakukan dengan ifelse:
julia> ifelse.(df .> 0.5, 0.5, df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.5 0.240867 0.5 0.331573 0.5
2 │ 0.225226 0.241412 0.0793279 0.418206 0.5 0.35275
3 │ 0.19913 0.0633375 0.5 0.280096 0.5 0.5
4 │ 0.5 0.230088 0.5 0.5 0.5 0.5
5 │ 0.0267573 0.0122425 0.5 0.331788 0.32658 0.00476749
Atau dengan clamp:
julia> clamp.(df, -Inf, 0.5)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.5 0.240867 0.5 0.331573 0.5
2 │ 0.225226 0.241412 0.0793279 0.418206 0.5 0.35275
3 │ 0.19913 0.0633375 0.5 0.280096 0.5 0.5
4 │ 0.5 0.230088 0.5 0.5 0.5 0.5
5 │ 0.0267573 0.0122425 0.5 0.331788 0.32658 0.00476749
Demikian pula, kita dapat menjepit nilai [0.1, 0.9] Periode:
julia> clamp.(df, 0.1, 0.9)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼────────────────────────────────────────────────────────────
1 │ 0.364225 0.690894 0.240867 0.720774 0.331573 0.549766
2 │ 0.225226 0.241412 0.1 0.418206 0.775367 0.35275
3 │ 0.19913 0.1 0.767805 0.280096 0.721995 0.9
4 │ 0.708132 0.230088 0.702677 0.9 0.9 0.66101
5 │ 0.1 0.1 0.549734 0.331788 0.32658 0.1
Yang penting adalah kita tidak perlu mempertahankan tipe elemen dari kolom sumber tetap.
Asumsikan bahwa kita ingin menetapkan nilai lebih besar dari 0.5 TIBA missing:
julia> ifelse.(df .> 0.5, missing, df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64? Float64? Float64? Float64? Float64? Float64?
─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ 0.364225 missing 0.240867 missing 0.331573 missing
2 │ 0.225226 0.241412 0.0793279 0.418206 missing 0.35275
3 │ 0.19913 0.0633375 missing 0.280096 missing missing
4 │ missing 0.230088 missing missing missing missing
5 │ 0.0267573 0.0122425 missing 0.331788 0.32658 0.00476749
Perhatikan bahwa operasi melakukan promosi otomatis jenis elemen kolom.
Sebagai aktivitas terakhir, pertimbangkan untuk mengambil sign(log(x) + 1) pada kerangka data kami:
julia> sign.(log.(df) .+ 1)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼──────────────────────────────────────────────────────
1 │ -1.0 1.0 -1.0 1.0 -1.0 1.0
2 │ -1.0 -1.0 -1.0 1.0 1.0 -1.0
3 │ -1.0 -1.0 1.0 -1.0 1.0 1.0
4 │ 1.0 -1.0 1.0 1.0 1.0 1.0
5 │ -1.0 -1.0 1.0 -1.0 -1.0 -1.0
Sekali lagi – semuanya mudah dan intuitif. Bingkai data berperilaku seperti matriks di semua operasi.
Saya harap Anda sekarang nyaman membuat kerangka data baru menggunakan broadcast.
Kita dapat beralih ke operasi di tempat pada kerangka data.
Secara umum, menempatkan bingkai data di sisi kanan misi siaran saja sudah cukup
operator untuk memperbaruinya di tempat:
julia> df2 = copy(df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.690894 0.240867 0.720774 0.331573 0.549766
2 │ 0.225226 0.241412 0.0793279 0.418206 0.775367 0.35275
3 │ 0.19913 0.0633375 0.767805 0.280096 0.721995 0.917259
4 │ 0.708132 0.230088 0.702677 0.947402 0.928979 0.66101
5 │ 0.0267573 0.0122425 0.549734 0.331788 0.32658 0.00476749
julia> df3 = df2
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.690894 0.240867 0.720774 0.331573 0.549766
2 │ 0.225226 0.241412 0.0793279 0.418206 0.775367 0.35275
3 │ 0.19913 0.0633375 0.767805 0.280096 0.721995 0.917259
4 │ 0.708132 0.230088 0.702677 0.947402 0.928979 0.66101
5 │ 0.0267573 0.0122425 0.549734 0.331788 0.32658 0.00476749
julia> df2 .= log.(df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────────
1 │ -1.00998 -0.369769 -1.42351 -0.32743 -1.10391 -0.598262
2 │ -1.49065 -1.42125 -2.53417 -0.87178 -0.254419 -1.04199
3 │ -1.6138 -2.75928 -0.26422 -1.27262 -0.325737 -0.0863653
4 │ -0.345124 -1.46929 -0.352858 -0.0540319 -0.0736689 -0.413987
5 │ -3.62095 -4.40285 -0.598321 -1.10326 -1.11908 -5.34594
julia> df2 === df3
true
Perhatikan bahwa dengan pemeriksaan terakhir, saya memastikannya df2 .= log.(df) berada di tempat.
Kami telah memperbarui konten dari df2dan jangan membuat objek baru.
Namun, terkadang hal-hal menjadi lebih rumit. mempertimbangkan df .> 0.5 operasi yang kami lakukan di atas:
julia> df2 .= df .> 0.5
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼──────────────────────────────────────────────────────
1 │ 0.0 1.0 0.0 1.0 0.0 1.0
2 │ 0.0 0.0 0.0 0.0 1.0 0.0
3 │ 0.0 0.0 1.0 0.0 1.0 1.0
4 │ 1.0 0.0 1.0 1.0 1.0 1.0
5 │ 0.0 0.0 1.0 0.0 0.0 0.0
Perhatikan bahwa ada perbedaan dari membuat kerangka data baru df .> 0.5.
Masalahnya adalah kolom dari df2 mempertahankan tipe aslinya. Ini yang diharapkan, seperti kita
ingin operasi sepenuhnya di tempat. Namun, terkadang Anda mungkin ingin berubah
jenis elemen kolom saat melakukan siaran. Ini mungkin, bagaimanapun,
maka Anda perlu menggunakan pengindeksan kerangka data dengan khusus ! pemilih baris pensinyalan
Ganti kolom itu diperlukan:
julia> df2[!, :] .= df .> 0.5
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Bool Bool Bool Bool Bool Bool
─────┼──────────────────────────────────────────
1 │ false true false true false true
2 │ false false false false true false
3 │ false false true false true true
4 │ true false true true true true
5 │ false false true false false false
julia> df3
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Bool Bool Bool Bool Bool Bool
─────┼──────────────────────────────────────────
1 │ false true false true false true
2 │ false false false false true false
3 │ false false true false true true
4 │ true false true true true true
5 │ false false true false false false
Memang, kami mendapatkan apa yang kami inginkan. Jadi begitu df3 giliran untuk meyakinkan Anda bahwa
semua operasi masih dilakukan pada objek kerangka data yang sama dan df2 Dan df3
masih menunjuk ke sana.
Izinkan saya memberi contoh perbedaan antara in-place dan column-replace
aktivitas sangat penting dan merupakan kejutan umum bagi pengguna baru.
Itu adalah kasus ketika kami ingin memperkenalkan missing nilai-nilai ke dalam kolom awalnya melarang mereka.
julia> df2 = copy(df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64 Float64 Float64 Float64 Float64 Float64
─────┼─────────────────────────────────────────────────────────────────
1 │ 0.364225 0.690894 0.240867 0.720774 0.331573 0.549766
2 │ 0.225226 0.241412 0.0793279 0.418206 0.775367 0.35275
3 │ 0.19913 0.0633375 0.767805 0.280096 0.721995 0.917259
4 │ 0.708132 0.230088 0.702677 0.947402 0.928979 0.66101
5 │ 0.0267573 0.0122425 0.549734 0.331788 0.32658 0.00476749
julia> df2 .= ifelse.(df .> 0.5, missing, df)
ERROR: MethodError: Cannot `convert` an object of type Missing to an object of type Float64
julia> df2[!, :] .= ifelse.(df .> 0.5, missing, df)
5×6 DataFrame
Row │ x1 x2 x3 x4 x5 x6
│ Float64? Float64? Float64? Float64? Float64? Float64?
─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ 0.364225 missing 0.240867 missing 0.331573 missing
2 │ 0.225226 0.241412 0.0793279 0.418206 missing 0.35275
3 │ 0.19913 0.0633375 missing 0.280096 missing missing
4 │ missing 0.230088 missing missing missing missing
5 │ 0.0267573 0.0122425 missing 0.331788 0.32658 0.00476749
Perhatikan bahwa df2 tidak diperbolehkan pada awalnya missing nilai di kolom manapun. Karena itudf2 .= ifelse.(df .> 0.5, missing, df) kegagalan. Namun, sebagai gantinya df2 .= melalui df2[!, :] .=
bekerja, karena ! pemilih secara eksplisit membutuhkan penimpaan kolom asli
dengan yang baru, dimungkinkan untuk mengubah tipenya.
Saya harap Anda menemukan contoh-contoh ini berguna dan mereka akan membantu Anda bekerja dengan DataFrames.jl lebih banyak lagi
dengan mudah dan percaya diri.
Sebagai komentar terakhir, izinkan saya menjelaskan alasannya df2 .= ifelse.(df .> 0.5, missing, df) sepenuhnya di tempat
(dan jangan ganti kolom dengan jenis elemen yang sesuai seperti df2[!, :] .=) karena ini adalah pertanyaan populer.
Ada tiga alasan untuk ini:
- kinerja: operasi yang sepenuhnya di tempat akan lebih cepat dan mengalokasikan lebih sedikit;
- aman: dalam kode produksi kita mungkin ingin memastikan jenis kolom tidak diubah secara tidak sengaja;
- konsistensi desain: operasi dirancang untuk berperilaku seperti bermain pada matriks
(penugasan siaran digunakan dengan matriks yang memungkinkan untuk mengubah jenis elemennya).
Terkait
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
#Tips #dan #trik #broadcasting #DataFrames.jl