Mengoptimalkan performa BigQuery DataFrames

BigQuery DataFrames membantu Anda menganalisis dan mengubah data di BigQuery menggunakan API yang kompatibel dengan pandas. Untuk membuat pemrosesan data Anda lebih cepat dan hemat biaya, Anda dapat menggunakan beberapa teknik untuk meningkatkan performa.

Dokumen ini menjelaskan cara berikut untuk mengoptimalkan performa:

Menggunakan mode pengurutan parsial

DataFrame BigQuery memiliki fitur mode pengurutan, yang menerapkan urutan baris tertentu untuk operasi seperti fungsi jendela dan gabungan. Anda dapat menentukan mode pengurutan dengan menyetel properti ordering_mode ke strict (dikenal sebagai mode pengurutan ketat, yang merupakan default) atau partial (dikenal sebagai mode pengurutan parsial). Menggunakan setelan partial dapat membuat kueri Anda lebih efisien.

Mode pengurutan parsial berbeda dengan mode pengurutan ketat. Mode pengurutan ketat mengatur semua baris dalam urutan tertentu. Pengurutan total ini membuat BigQuery DataFrames berfungsi lebih baik dengan pandas, sehingga Anda dapat mengakses baris berdasarkan urutannya menggunakan properti DataFrame.iloc. Namun, pengurutan total dan indeks berurutan defaultnya mencegah filter pada kolom atau baris mengurangi jumlah data yang dipindai. Pencegahan ini terjadi kecuali jika Anda menerapkan filter tersebut sebagai parameter ke fungsi read_gbq dan read_gbq_table. Untuk mengurutkan semua baris dalam DataFrame, BigQuery DataFrames membuat hash semua baris. Operasi ini dapat menyebabkan pemindaian data penuh yang mengabaikan filter baris dan kolom.

Mode pengurutan parsial menghentikan DataFrame BigQuery membuat urutan total untuk semua baris dan menonaktifkan fitur yang memerlukan urutan total, seperti properti DataFrame.iloc. Mode pengurutan parsial juga menetapkan class DefaultIndexKind ke indeks null, bukan ke indeks berurutan.

Saat Anda memfilter objek DataFrame menggunakan mode pengurutan parsial, BigQuery DataFrames tidak menghitung baris mana yang tidak ada dalam indeks berurutan. Mode pengurutan parsial juga tidak otomatis menggabungkan data berdasarkan indeks. Pendekatan ini dapat meningkatkan efisiensi kueri Anda. Namun, baik Anda menggunakan mode pengurutan ketat default atau mode pengurutan parsial, BigQuery DataFrames API berfungsi seperti pandas API yang sudah dikenal.

Dengan mode pengurutan parsial dan ketat, Anda membayar resource BigQuery yang Anda gunakan. Namun, menggunakan mode pengurutan parsial dapat menurunkan biaya saat bekerja dengan tabel berpartisi dan dikelompokkan yang besar. Pengurangan biaya ini terjadi karena filter baris pada kolom cluster dan partisi mengurangi jumlah data yang diproses.

Mengaktifkan mode pemesanan sebagian

Untuk menggunakan pengurutan parsial, tetapkan properti ordering_mode ke partial sebelum melakukan operasi lain dengan DataFrame BigQuery, seperti yang ditunjukkan dalam contoh kode berikut:

import bigframes.pandas as bpd

bpd.options.bigquery.ordering_mode = "partial"

Mode pengurutan parsial mencegah penggabungan implisit objek BigQuery DataFrames yang tidak terkait karena tidak memiliki indeks berurutan. Sebagai gantinya, Anda harus memanggil metode DataFrame.merge secara eksplisit untuk menggabungkan dua objek DataFrame BigQuery yang berasal dari ekspresi tabel yang berbeda.

Fitur Series.unique() dan Series.drop_duplicates() tidak berfungsi dengan mode pengurutan parsial. Sebagai gantinya, gunakan metode groupby untuk menemukan nilai unik, seperti yang ditunjukkan dalam contoh berikut:

# Avoid order dependency by using groupby instead of drop_duplicates.
unique_col = df.groupby(["column"], as_index=False).size().drop(columns="size")

Dengan mode pengurutan parsial, output fungsi DataFrame.head(n) dan Series.head(n) mungkin tidak sama setiap kali Anda menjalankannya. Untuk mendownload sampel data acak kecil, gunakan metode DataFrame.peek() atau Series.peek().

Untuk tutorial mendetail yang menggunakan properti ordering_mode = "partial" ini, lihat Menganalisis download paket dari PyPI dengan BigQuery DataFrames.

Pemecahan masalah

Karena BigQuery DataFrames dalam mode pengurutan parsial terkadang tidak memiliki pengurutan atau indeks, Anda mungkin mengalami masalah berikut saat menggunakan beberapa metode yang kompatibel dengan pandas.

Error pesanan diperlukan

Beberapa fitur, seperti fungsi DataFrame.head() dan DataFrame.iloc, memerlukan pengurutan. Untuk daftar fitur yang memerlukan pengurutan, lihat kolom Requires ordering di API pandas yang didukung.

Jika objek tidak memiliki pengurutan, operasi akan gagal dengan pesan OrderRequiredError seperti berikut: OrderRequiredError: Op iloc requires an ordering. Use .sort_values or .sort_index to provide an ordering.

Seperti yang dinyatakan dalam pesan error, Anda dapat memberikan pengurutan menggunakan metode DataFrame.sort_values() untuk mengurutkan menurut satu atau beberapa kolom. Metode lain, seperti DataFrame.groupby(), secara implisit memberikan pengurutan total berdasarkan pengelompokan menurut kunci.

Jika pengurutan bukan pengurutan total yang sepenuhnya stabil untuk semua baris, operasi selanjutnya mungkin menampilkan pesan AmbiguousWindowWarning seperti berikut: AmbiguousWindowWarning: Window ordering may be ambiguous, this can cause unstable results.

Jika pekerjaan Anda dapat menangani hasil yang tidak selalu sama, atau jika Anda dapat memeriksa secara manual bahwa pengurutan Anda adalah pengurutan total, Anda dapat memfilter pesan AmbiguousWindowWarning dengan cara ini:

import warnings

import bigframes.exceptions

warnings.simplefilter(
    "ignore", category=bigframes.exceptions.AmbiguousWindowWarning
)

Error indeks null

Beberapa fitur, seperti properti DataFrame.unstack() dan Series.interpolate(), memerlukan indeks. Untuk mengetahui daftar fitur yang memerlukan indeks, lihat kolom Memerlukan indeks di API pandas yang didukung.

Saat Anda menggunakan operasi yang memerlukan indeks dengan mode pengurutan parsial, operasi akan memunculkan pesan NullIndexError seperti berikut: NullIndexError: DataFrame cannot perform interpolate as it has no index. Set an index using set_index.

Seperti yang dinyatakan dalam pesan error, Anda dapat memberikan indeks menggunakan metode DataFrame.set_index() untuk mengurutkan menurut satu atau beberapa kolom. Metode lain, seperti DataFrame.groupby(), secara implisit memberikan indeks berdasarkan pengelompokan menurut kunci, kecuali jika parameter as_index=False ditetapkan.

Meng-cache hasil setelah operasi yang mahal

BigQuery DataFrames menyimpan operasi secara lokal dan menunda menjalankan kueri hingga kondisi tertentu terpenuhi. Hal ini dapat menyebabkan operasi yang sama berjalan beberapa kali di berbagai kueri.

Untuk menghindari pengulangan operasi yang mahal, simpan hasil sementara dengan metode cache(), seperti yang ditunjukkan dalam contoh berikut:

# Assume you have 3 large dataframes "users", "group" and "transactions"

# Expensive join operations
final_df = users.join(groups).join(transactions)
final_df.cache()
# Subsequent derived results will reuse the cached join
print(final_df.peek())
print(len(final_df[final_df["completed"]]))
print(final_df.groupby("group_id")["amount"].mean().peek(30))

Metode ini membuat tabel BigQuery sementara untuk menyimpan hasil Anda. Anda akan dikenai biaya untuk penyimpanan tabel sementara ini di BigQuery.

Melihat pratinjau data dengan metode peek()

BigQuery DataFrames menawarkan dua metode API untuk melihat pratinjau data:

  • peek(n) menampilkan n baris data, dengan n adalah jumlah baris.
  • head(n) menampilkan n baris pertama data, bergantung pada konteksnya, dengan n adalah jumlah baris.

Gunakan metode head() hanya jika urutan data penting, misalnya, jika Anda menginginkan lima nilai terbesar dalam kolom. Dalam kasus lain, gunakan metode peek() untuk pengambilan data yang lebih efisien, seperti yang ditunjukkan dalam contoh kode berikut:

import bigframes.pandas as bpd

# Read the "Penguins" table into a dataframe
df = bpd.read_gbq("bigquery-public-data.ml_datasets.penguins")

# Preview 3 random rows
df.peek(3)

Anda juga dapat menggunakan metode peek() untuk mendownload sampel data kecil acak saat menggunakan mode pengurutan parsial.

Menunda pengambilan data repr()

Anda dapat memanggil metode repr() di BigQuery DataFrames dengan notebook atau debugger IDE Anda. Panggilan ini memicu panggilan head() yang mengambil data sebenarnya. Pengambilan ini dapat memperlambat proses coding dan proses debug iteratif Anda serta menimbulkan biaya.

Untuk mencegah metode repr() mengambil data, tetapkan atribut repr_mode ke "deferred", seperti yang ditunjukkan dalam contoh berikut:

import bigframes.pandas as bpd

bpd.options.display.repr_mode = "deferred"

Dalam mode ditangguhkan, Anda hanya dapat melihat pratinjau data dengan panggilan peek() dan head() eksplisit.

Langkah berikutnya