Saya mengerjakan kerangka data dengan dua kolom, mvv dan hitungan.
+---+-----+
|mvv|count|
+---+-----+
| 1 | 5 |
| 2 | 9 |
| 3 | 3 |
| 4 | 1 |
saya ingin mendapatkan dua daftar yang berisi nilai mvv dan nilai hitungan. Sesuatu seperti
mvv = [1,2,3,4]
count = [5,9,3,1]
Jadi, saya mencoba kode berikut: Baris pertama harus mengembalikan daftar baris python. Saya ingin melihat nilai pertama:
mvv_list = mvv_count_df.select('mvv').collect()
firstvalue = mvv_list[0].getInt(0)
Tetapi saya mendapatkan pesan kesalahan dengan baris kedua:
AttributeError: getInt
python
apache-spark
pyspark
spark-dataframe
a.moussa
sumber
sumber
list(df.select('mvv').toPandas()['mvv'])
. Panah diintegrasikan ke PySpark yang dipercepattoPandas
secara signifikan. Jangan gunakan pendekatan lain jika Anda menggunakan Spark 2.3+. Lihat jawaban saya untuk detail pembandingan lebih lanjut.Jawaban:
Lihat, mengapa cara yang Anda lakukan ini tidak berhasil. Pertama, Anda mencoba mendapatkan integer dari Row Type, output dari collect Anda adalah seperti ini:
Jika Anda mengambil sesuatu seperti ini:
Anda akan mendapatkan
mvv
nilainya. Jika Anda menginginkan semua informasi dari array Anda dapat mengambil sesuatu seperti ini:Tetapi jika Anda mencoba hal yang sama untuk kolom lain, Anda mendapatkan:
Ini terjadi karena
count
metode bawaan. Dan kolom tersebut memiliki nama yang sama dengancount
. Solusi untuk melakukan ini adalah mengubah nama kolomcount
menjadi_count
:Tetapi solusi ini tidak diperlukan, karena Anda dapat mengakses kolom menggunakan sintaks kamus:
Dan akhirnya akan berhasil!
sumber
select('count')
penggunaan ini seperti ini:count_list = [int(i.count) for i in mvv_list.collect()]
Saya akan menambahkan contoh ke respons.[i.['count'] for i in mvv_list.collect()]
bekerja untuk membuatnya eksplisit menggunakan kolom bernama 'count' dan bukancount
fungsinyaMengikuti satu baris memberikan daftar yang Anda inginkan.
sumber
Ini akan memberi Anda semua elemen sebagai daftar.
sumber
Kode berikut akan membantu Anda
sumber
Pada data saya, saya mendapatkan tolok ukur ini:
0,52 dtk
0,271 dtk
0,427 dtk
Hasilnya sama saja
sumber
toLocalIterator
alih-alihcollect
itu seharusnya lebih hemat memori[row[col] for row in data.toLocalIterator()]
Jika Anda mendapatkan error di bawah ini:
Kode ini akan menyelesaikan masalah Anda:
sumber
Saya menjalankan analisis benchmarking dan
list(mvv_count_df.select('mvv').toPandas()['mvv'])
merupakan metode tercepat. Saya sangat terkejut.Saya menjalankan pendekatan yang berbeda pada 100 ribu / 100 juta kumpulan data baris menggunakan cluster 5 node i3.xlarge (setiap node memiliki 30,5 GB RAM dan 4 core) dengan Spark 2.4.5. Data didistribusikan secara merata pada 20 file Parket terkompresi tajam dengan satu kolom.
Berikut hasil benchmarking (runtime dalam detik):
Aturan emas yang harus diikuti saat mengumpulkan data di node driver:
toPandas
meningkat secara signifikan di Spark 2.3 . Ini mungkin bukan pendekatan terbaik jika Anda menggunakan versi Spark lebih awal dari 2.3.Lihat di sini untuk detail lebih lanjut / hasil pembandingan.
sumber
Solusi yang mungkin adalah menggunakan
collect_list()
fungsi daripyspark.sql.functions
. Ini akan menggabungkan semua nilai kolom menjadi larik pyspark yang diubah menjadi daftar python saat dikumpulkan:sumber