Pandas & NumPy Academy · Pelajaran

CSV Penstriman dengan chunksize

Baca CSV besar dalam kelompok bersaiz tetap dengan pd.read_csv(chunksize=), proses setiap kelompok dan gabungkan atau kumpulkan hasil.

Pelajaran 1 daripada 413 langkah

CSV Penstriman dengan chunksize ialah pelajaran Pandas & NumPy Academy percuma di CoddyKit. Ini ialah pelajaran 1 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Pandas & NumPy Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Pandas & NumPy Academy merangkumi sejumlah 4 pelajaran.

Masalah dengan Fail CSV Besar

Apabila fail CSV lebih besar daripada RAM yang tersedia — contohnya, fail log 50 GB pada mesin dengan memori 16 GB — pemanggilan pd.read_csv('file.csv') gagal dengan MemoryError atau menyebabkan sistem menggunakan ruang swap secara berlebihan sehingga menjadi terlalu perlahan untuk digunakan. Penyelesaiannya ialah pembacaan berketul: bukannya memuatkan seluruh fail sekali gus, Anda memprosesnya dalam bahagian bersaiz tetap dan mengumpulkan hasil tanpa menyimpan semuanya dalam memori pada masa yang sama.

Parameter chunksize dalam read_csv

Memberikan chunksize=N kepada pd.read_csv() mengembalikan iterator TextFileReader, bukannya DataFrame. Setiap lelaran menghasilkan DataFrame dengan paling banyak N baris. Fail dibaca secara malas — tiada data dimuatkan sehingga Anda meminta ketul seterusnya. Iterator ini boleh digunakan dalam gelung for atau dihantar kepada pd.concat(). Pilih chunksize yang cukup besar untuk I/O yang cekap (contohnya, 10,000–100,000 baris), tetapi cukup kecil untuk dimuatkan dengan selesa dalam memori.

import pandas as pd

# Returns a TextFileReader iterator, NOT a DataFrame
chunks = pd.read_csv('sales_data.csv', chunksize=10000)
print(type(chunks))  # <class 'pandas.io.parsers.readers.TextFileReader'>

for chunk in chunks:
    print(f'Chunk shape: {chunk.shape}')
    # process each chunk independently
    break   # just show the first chunk here

Memproses Setiap Ketul Secara Berasingan

Pola yang paling biasa ialah melakukan transformasi atau penapisan pada setiap ketul dan mengumpulkan hasilnya dalam senarai, kemudian menggabungkannya. Contohnya, Anda boleh menapis baris yang sepadan dengan syarat, mengira statistik bagi setiap ketul atau memilih lajur yang diperlukan sahaja. Bekerja pada subset bermaksud hanya ketul semasa menggunakan memori, manakala bahagian fail yang lain tidak disentuh. Selepas gelung tamat, satu pd.concat(results) menggabungkan DataFrame akhir.

import pandas as pd

results = []
for chunk in pd.read_csv('orders.csv', chunksize=50000):
    # Keep only high-value orders
    filtered = chunk[chunk['amount'] > 1000]
    results.append(filtered)

# Combine all filtered chunks
high_value = pd.concat(results, ignore_index=True)
print('High-value orders:', len(high_value))

Mengumpulkan Agregat Merentas Ketul

Kadangkala Anda tidak perlu menyimpan sebarang baris — Anda hanya memerlukan agregat berjalan. Jejaki jumlah, kiraan atau min/maksimum berjalan merentas ketul tanpa membina senarai DataFrame. Ini ialah pola yang paling cekap dari segi memori kerana penggunaan memori kekal malar tanpa mengira saiz fail. Pada akhir proses, kira statistik akhir daripada pengumpul Anda.

import pandas as pd

total_revenue = 0.0
total_rows = 0

for chunk in pd.read_csv('sales.csv', chunksize=100000):
    total_revenue += chunk['revenue'].sum()
    total_rows += len(chunk)

print(f'Processed {total_rows:,} rows')
print(f'Total revenue: ${total_revenue:,.2f}')

Menentukan dtype untuk Mempercepat Pembacaan Berketul

Secara lalai, Pandas membuat inferens terhadap dtype lajur daripada data, yang memerlukan setiap ketul diimbas dua kali (sekali untuk membuat inferens dan sekali untuk menghuraikan). Menyediakan argumen dtype mengelakkan lebihan kerja ini dan juga mencegah ketidakselarasan dtype antara ketul. Contohnya, lajur yang kebanyakannya mengandungi integer tetapi mempunyai satu sel kosong mungkin dibuat inferens sebagai float64 dalam satu ketul dan object dalam ketul yang lain. Menentukan dtype secara jelas memastikan pembacaan yang konsisten dan lebih pantas merentas semua ketul.

import pandas as pd

dtype_map = {
    'order_id': 'int32',
    'customer_id': 'int32',
    'amount': 'float32',
    'category': 'category'
}

for chunk in pd.read_csv('orders.csv',
                         chunksize=50000,
                         dtype=dtype_map,
                         parse_dates=['order_date']):
    print(chunk.dtypes)
    break

Memilih Lajur yang Diperlukan Sahaja

Gunakan parameter usecols untuk memuatkan lajur yang diperlukan oleh analisis Anda sahaja. Jika CSV mempunyai 50 lajur tetapi agregasi Anda hanya menggunakan 3 lajur, tiada sebab untuk menghuraikan 47 lajur yang lain. Menggabungkan usecols dengan chunksize mengurangkan masa I/O dan penggunaan memori dengan ketara. Ini ialah salah satu pengoptimuman yang paling mudah dan paling berkesan untuk pemprosesan CSV besar.

import pandas as pd

# Only read the three columns we actually need
for chunk in pd.read_csv(
    'large_transactions.csv',
    chunksize=100000,
    usecols=['date', 'amount', 'region']
):
    print(chunk.columns.tolist())
    print(chunk.memory_usage(deep=True).sum() / 1e6, 'MB per chunk')
    break

Agregasi GroupBy dalam Ketul

Melakukan agregasi groupby merentas ketul memerlukan pengumpulan hasil separa. Kira groupby dalam setiap ketul, kemudian gabungkan hasil tersebut menggunakan groupby kedua pada hasil separa yang telah digabungkan. Contohnya, untuk mendapatkan jumlah jualan mengikut rantau merentas fail 10 GB, kumpulkan jumlah rantau bagi setiap ketul dalam senarai, kemudian gabungkan dan lakukan pengumpulan mengikut kumpulan sekali lagi. Pola agregasi dua laluan ini kadangkala dipanggil pendekatan map-reduce.

import pandas as pd

partials = []
for chunk in pd.read_csv('sales.csv',
                         chunksize=100000,
                         usecols=['region', 'revenue']):
    partial = chunk.groupby('region')['revenue'].sum()
    partials.append(partial)

# Combine partial sums
final = pd.concat(partials).groupby(level=0).sum()
print('Revenue by region:')
print(final.sort_values(ascending=False))

Mengendalikan Ralat Penghuraian Merentas Ketul

Fail CSV besar daripada sumber luaran sering mempunyai baris tidak sah — koma tambahan, pengekodan yang salah atau baris terpotong. Gunakan on_bad_lines='skip' (Pandas 1.3+) atau error_bad_lines=False (Pandas versi lama) untuk melangkau baris tidak sah secara senyap, dan encoding='latin-1' jika penghuraian UTF-8 gagal. Jejaki ketul yang menghasilkan ralat dengan blok cuba-kecuali di sekeliling pemprosesan setiap ketul untuk membina pipeline yang teguh dan tidak terhenti akibat satu baris tidak sah dalam fail 10 juta baris.

import pandas as pd

bad_chunks = []
all_chunks = []

for i, chunk in enumerate(pd.read_csv(
    'raw_data.csv',
    chunksize=50000,
    on_bad_lines='skip',
    encoding='utf-8',
    encoding_errors='replace'
)):
    try:
        # Your transformation here
        all_chunks.append(chunk)
    except Exception as e:
        bad_chunks.append((i, str(e)))
        print(f'Chunk {i} error: {e}')

print(f'Processed {len(all_chunks)} chunks, {len(bad_chunks)} errors')

Penulisan Berketul ke Fail Output

Apabila output yang diproses juga besar, tulis hasil secara berperingkat dan bukannya mengumpulkan semuanya dalam memori sebelum menulis pada akhir. Buka fail CSV dan tambahkan setiap ketul yang diproses menggunakan mode='a' serta header=False untuk ketul berikutnya. Ini memastikan pipeline output menggunakan jumlah memori yang malar dan membolehkan Anda memeriksa hasil separa sebelum pelaksanaan lengkap selesai.

import pandas as pd

first_chunk = True
for chunk in pd.read_csv('input.csv', chunksize=100000):
    # Transform
    processed = chunk[chunk['status'] == 'active'].copy()
    processed['revenue_usd'] = processed['revenue'] * 1.10

    # Write incrementally
    mode = 'w' if first_chunk else 'a'
    processed.to_csv('output.csv',
                     mode=mode,
                     header=first_chunk,
                     index=False)
    first_chunk = False

print('Done writing output.csv')

Menganggarkan Saiz Ketul Optimum

Memilih chunksize ialah suatu imbangan: nilai terlalu kecil bermaksud banyak lelaran gelung Python dan lebihan kerja yang tinggi; nilai terlalu besar bermaksud ketul tidak muat dalam RAM. Pendekatan praktikal ialah memuatkan satu ketul, mengukur memorinya dengan chunk.memory_usage(deep=True).sum() dan menetapkan chunksize supaya setiap ketul menggunakan kira-kira 10–20% RAM yang tersedia. Python's psutil.virtual_memory().available memberikan RAM yang tersedia semasa masa jalan, sekali gus membolehkan pengiraan chunksize secara adaptif.

import pandas as pd

# Sample 1000 rows to estimate per-row memory
sample = pd.read_csv('big_file.csv', nrows=1000)
bytes_per_row = sample.memory_usage(deep=True).sum() / 1000
print(f'Bytes per row: {bytes_per_row:.0f}')

# Target: use at most 500 MB per chunk
target_bytes = 500 * 1024 * 1024
optimal_chunksize = int(target_bytes / bytes_per_row)
print(f'Recommended chunksize: {optimal_chunksize:,}')

Menggabungkan Hasil Berketul dengan Cekap

Apabila mengumpulkan banyak DataFrame ketul dalam senarai dan kemudian menggabungkannya, ambil perhatian bahawa pemanggilan pd.concat pada ratusan bingkai kecil adalah perlahan akibat peruntukan memori berulang. Pola yang lebih baik ialah melakukan agregasi dalam setiap ketul dan hanya menyimpan hasil agregat yang kecil, bukannya ketul penuh. Jika Anda benar-benar memerlukan semua baris, menulis ke fail Parquet secara berperingkat (menggunakan pyarrow) adalah lebih pantas daripada pd.concat pada akhir proses.

import pandas as pd

# Efficient: aggregate first, small list of scalars
running_total = 0
running_count = 0

for chunk in pd.read_csv('sales.csv', chunksize=100000):
    running_total += chunk['amount'].sum()
    running_count += chunk['amount'].count()

print(f'Mean amount: {running_total / running_count:.2f}')

# Avoid: accumulating full chunk DataFrames
# results = []
# for chunk in reader:
#     results.append(chunk)   # memory grows to full file size
# df = pd.concat(results)     # slow for hundreds of chunks

Semakan Ringkas

Uji pemahaman Anda tentang konsep Analisis Data daripada pelajaran ini.

Imbas Kembali Pelajaran

Dalam pelajaran ini, Anda mempelajari: chunksize dalam pd.read_csv mengembalikan iterator DataFrame yang membolehkan pemprosesan fail besar dengan penggunaan memori yang cekap, argumen usecols dan dtype mengurangkan memori bagi setiap ketul dan mempercepat penghuraian, serta pengumpul berjalan (sum, count, partials) mengelakkan pembinaan senarai yang mengandungi semua ketul. Seterusnya, kita akan melihat pola agregasi berperingkat merentas ketul dengan lebih mendalam.

Percuma untuk bermula

Pelajari Python dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “CSV Penstriman dengan chunksize” percuma?

Ya — teks penuh “CSV Penstriman dengan chunksize” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Pandas & NumPy Academy, tingkat taraf kepada CoddyKit PRO. Kursus Pandas & NumPy Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “CSV Penstriman dengan chunksize”?

Baca CSV besar dalam kelompok bersaiz tetap dengan pd.read_csv(chunksize=), proses setiap kelompok dan gabungkan atau kumpulkan hasil. Anda berlatih Pandas & NumPy Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Pandas & NumPy Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Pandas & NumPy Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 1 daripada 4.

Berapa lamakah pelajaran “CSV Penstriman dengan chunksize” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Pandas & NumPy Academy ini?

Ya. Setiap pelajaran Pandas & NumPy Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. CSV Penstriman dengan chunksize
  2. Agregasi Berperingkat Merentas Kelompok
  3. Pengenalan kepada DataFrames Dask
  4. Parquet: Storan Kolumnar Pantas
← Kembali ke Pandas & NumPy Academy