Saya memiliki DataFrame berikut di mana salah satu kolomnya adalah objek (sel tipe daftar):
df=pd.DataFrame({'A':[1,2],'B':[[1,2],[1,2]]})
df
Out[458]:
A B
0 1 [1, 2]
1 2 [1, 2]
Output yang saya harapkan adalah:
A B
0 1 1
1 1 2
3 2 1
4 2 2
Apa yang harus saya lakukan untuk mencapai ini?
Pertanyaan terkait
pandas: Jika konten sel berupa daftar, buat baris untuk setiap elemen dalam daftar
Pertanyaan dan jawaban bagus tetapi hanya menangani satu kolom dengan daftar (Dalam jawaban saya fungsi self-def akan berfungsi untuk beberapa kolom, juga jawaban yang diterima adalah penggunaan yang paling memakan waktu apply
, yang tidak disarankan, periksa info lebih lanjut Kapan saya harus mau menggunakan pandas apply () dalam kode saya? )
Jawaban:
Sebagai pengguna dengan
R
danpython
, saya telah melihat jenis pertanyaan ini beberapa kali.Di R, mereka memiliki fungsi bawaan dari paket yang
tidyr
dipanggilunnest
. Namun diPython
(pandas
) tidak ada fungsi bawaan untuk jenis pertanyaan ini.Saya tahu
object
kolomtype
selalu membuat data sulit untuk diubah denganpandas
fungsi '. Ketika saya menerima data seperti ini, hal pertama yang terlintas di benak saya adalah 'meratakan' atau mengosongkan kolom.Saya menggunakan
pandas
danpython
fungsi untuk jenis pertanyaan ini. Jika Anda khawatir tentang kecepatan solusi di atas, periksa jawaban pengguna3483203, karena dia menggunakannumpy
dan sebagian besar waktunumpy
lebih cepat. Saya merekomendasikanCpython
dannumba
jika kecepatan penting dalam kasus Anda.Metode 0 [pandas> = 0,25]
Mulai dari panda 0,25 , jika Anda hanya perlu meledakkan satu kolom, Anda dapat menggunakan
explode
fungsi:Metode 1
apply + pd.Series
(mudah dipahami tetapi dalam hal kinerja tidak disarankan.)Metode 2
Menggunakan
repeat
denganDataFrame
konstruktor, buat ulang kerangka data Anda (bagus dalam kinerja, tidak bagus di banyak kolom)Metode 2.1
misalnya selain A kita memiliki A.1 ..... An Jika kita masih menggunakan metode ( Metode 2 ) di atas sulit bagi kita untuk membuat ulang kolom satu per satu.
Solusi:
join
ataumerge
denganindex
setelah 'tidak ada' kolom tunggalJika Anda ingin urutan kolom sama persis seperti sebelumnya, tambahkan
reindex
di bagian akhir.Metode 3
membuat ulang file
list
Jika lebih dari dua kolom, gunakan
Metode 4
menggunakan
reindex
atauloc
Metode 5
ketika daftar hanya berisi nilai unik:
Metode 6
menggunakan
numpy
untuk kinerja tinggi:Metode 7
menggunakan fungsi dasar
itertools
cycle
danchain
: Solusi python murni hanya untuk bersenang-senangMenggeneralisasi ke banyak kolom
Fungsi self-def:
Unnesting berdasarkan kolom
Semua metode di atas berbicara tentang penarikan vertikal dan meledak, Jika Anda perlu mengeluarkan daftar horizontal , Periksa dengan
pd.DataFrame
konstruktorFungsi diperbarui
Hasil Tes
sumber
ValueError: zero-dimensional arrays cannot be concatenated
. Juga, beberapa dari ini bahkan mencoba untuk menggeneralisasi ke kerangka data yang lebih luas. Yang mengklaim masih mengharuskan Anda mengetahui berapa banyak kolom yang dimiliki df Anda sebelumnya.[]
harus jatuh, apakah kamu benar-benar mencoba contoh, dari milikku? Atau Anda memiliki situasi yang berbeda?Pilihan 1
Jika semua sublist di kolom lain memiliki panjang yang sama,
numpy
dapat menjadi opsi yang efisien di sini:pilihan 2
Jika sublist memiliki panjang yang berbeda, Anda memerlukan langkah tambahan:
Pilihan 3
Saya mengambil bidikan untuk menggeneralisasi ini agar bekerja untuk meratakan
N
kolom danM
kolom ubin , saya akan bekerja nanti untuk membuatnya lebih efisien:Fungsi
Pengaturan waktu
Performa
sumber
df.explode
metode baru .Meledakkan kolom seperti daftar telah disederhanakan secara signifikan di panda 0.25 dengan penambahan
explode()
metode:Di luar:
sumber
Salah satu alternatifnya adalah menerapkan resep meshgrid di atas baris kolom ke tidak terkendali:
Keluaran
sumber
5 sen saya:
dan 5 lainnya
keduanya menghasilkan hal yang sama
sumber
Karena biasanya panjang sublist berbeda dan join / merge jauh lebih mahal secara komputasi. Saya menguji ulang metode untuk sublist panjang yang berbeda dan kolom yang lebih normal.
MultiIndex juga merupakan cara yang lebih mudah untuk menulis dan memiliki performa yang hampir sama dengan cara numpy.
Anehnya, cara pemahaman implementasi saya memiliki kinerja terbaik.
Performa
Waktu relatif dari setiap metode
sumber
Saya menggeneralisasi masalah sedikit agar dapat diterapkan ke lebih banyak kolom.
Ringkasan dari solusi saya:
Contoh lengkapnya:
Ledakan sebenarnya dilakukan dalam 3 baris. Sisanya adalah kosmetik (ledakan multi kolom, penanganan string, bukan daftar di kolom ledakan, ...).
Penghargaan untuk jawaban WeNYoBen
sumber
Masalah Setup
Asumsikan ada beberapa kolom dengan objek panjang yang berbeda di dalamnya
Jika panjangnya sama, mudah bagi kita untuk berasumsi bahwa elemen yang berbeda-beda itu bertepatan dan harus "di-zip" bersama.
Namun, asumsi tersebut mendapat tantangan ketika kita melihat objek dengan panjang yang berbeda, haruskah kita "zip", jika demikian, bagaimana kita menangani kelebihan di salah satu objek. ATAU , mungkin kita menginginkan produk dari semua objek. Ini akan menjadi besar dengan cepat, tetapi mungkin itulah yang diinginkan.
ATAU
Fungsi
Fungsi ini menangani
zip
atauproduct
berdasarkan parameter dengan baik dan mengasumsikanzip
sesuai dengan panjang objek terpanjang denganzip_longest
Di-zip
Produk
Setup Baru
Memvariasikan contoh sedikit
Di-zip
Produk
sumber
Sesuatu yang sangat tidak disarankan (setidaknya berfungsi dalam kasus ini):
concat
+sort_index
+iter
+apply
+next
.Sekarang:
Adalah:
Jika peduli dengan indeks:
Sekarang:
Adalah:
sumber
Ada pendapat tentang metode ini yang saya pikirkan? atau apakah melakukan concat dan melt dianggap terlalu "mahal"?
sumber
Saya memiliki cara lain yang baik untuk menyelesaikan ini ketika Anda memiliki lebih dari satu kolom untuk meledak.
Saya ingin meledakkan kolom B dan C. Pertama saya meledakkan B, kedua C. Kemudian saya menjatuhkan B dan C dari df asli. Setelah itu saya akan melakukan index join pada 3 dfs.
sumber
sumber
sumber
Dalam kasus saya dengan lebih dari satu kolom untuk meledak, dan dengan panjang variabel untuk array yang perlu tidak teruji.
Saya akhirnya menerapkan fungsi pandas 0.25 baru
explode
dua kali, kemudian menghapus duplikat yang dihasilkan dan itu berhasil!sumber