0Pricing
Pandas & NumPy Academy · บทเรียน

Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง

เขียน Pandas DataFrame เป็น Parquet ด้วย to_parquet() อ่านกลับได้เร็วกว่าการใช้ CSV และใช้การเลือกเฉพาะคอลัมน์เพื่อโหลดเฉพาะฟิลด์ที่จำเป็น

Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

Parquet คืออะไร

Apache Parquet คือรูปแบบไฟล์ไบนารีแบบคอลัมน์ที่ออกแบบมาสำหรับงานวิเคราะห์ข้อมูล ต่างจาก CSV ซึ่งจัดเก็บข้อมูลทีละแถวในรูปข้อความ Parquet จะจัดเก็บแต่ละคอลัมน์ไว้ในบล็อกต่อเนื่อง บีบอัดข้อมูลอย่างมีประสิทธิภาพ และเข้ารหัสข้อมูลเมตา ทำให้ทำงานได้เร็วขึ้นอย่างมากกับการสืบค้นที่อ่านเพียงไม่กี่คอลัมน์จากตารางที่มีหลายคอลัมน์ Parquet เป็นรูปแบบมาตรฐานโดยพฤตินัยในคลังข้อมูล (AWS S3, Google Cloud Storage) และได้รับการรองรับโดยตรงจาก Pandas, Dask, Spark และ BigQuery

การเขียน Parquet ด้วย to_parquet()

การแปลง Pandas DataFrame เป็น Parquet ทำได้ด้วยการเรียกใช้เมธอดเพียงครั้งเดียว: df.to_parquet('output.parquet') กลไกเริ่มต้นคือ pyarrow (ติดตั้งด้วย pip install pyarrow) Parquet จะรักษาชนิดข้อมูลของคอลัมน์ไว้อย่างถูกต้อง — ไม่ต้องกังวลว่าคอลัมน์วันที่จะถูกอ่านกลับมาเป็นข้อความอีกต่อไป นอกจากนี้ยังรองรับการบีบอัดข้อมูลในตัวผ่านพารามิเตอร์ compression โดย 'snappy' ให้ความเร็วในการอ่านและเขียนสูงพร้อมการบีบอัดระดับปานกลาง ส่วน 'gzip' ให้การบีบอัดที่สูงกว่าแลกกับความเร็วที่ลดลง

import pandas as pd
import numpy as np

# Create a sample DataFrame
np.random.seed(0)
df = pd.DataFrame({
    'date': pd.date_range('2024-01-01', periods=100000, freq='T'),
    'value': np.random.randn(100000),
    'category': np.random.choice(['A', 'B', 'C'], 100000)
})

# Write to Parquet
df.to_parquet('data.parquet', index=False, compression='snappy')
print('Written to data.parquet')

การอ่าน Parquet ด้วย read_parquet()

pd.read_parquet('output.parquet') จะอ่านไฟล์กลับเข้าไปเป็น DataFrame เมื่อเทียบกับการอ่าน CSV ที่เทียบเท่ากัน การอ่าน Parquet มักเร็วกว่า 5–10 เท่าสำหรับตารางที่มีหลายคอลัมน์ ชนิดข้อมูลจะถูกเก็บรักษาไว้อย่างถูกต้อง — วันที่ยังคงเป็น datetime64, หมวดหมู่ยังคงเป็น category และจำนวนเต็มยังคงเป็น int32 หรือ int64 ตามที่จัดเก็บไว้ ไม่จำเป็นต้องอนุมานชนิดข้อมูล เนื่องจากข้อมูลเมตาถูกฝังอยู่ในไฟล์

import pandas as pd
import time

# Read Parquet
start = time.time()
df = pd.read_parquet('data.parquet')
print(f'Read Parquet: {time.time()-start:.3f}s')
print(df.dtypes)
print(df.shape)

การลดคอลัมน์: อ่านเฉพาะคอลัมน์ที่ต้องการ

ข้อได้เปรียบที่สำคัญที่สุดของการจัดเก็บแบบคอลัมน์คือการลดคอลัมน์: คุณสามารถอ่านเฉพาะคอลัมน์ที่ต้องการได้โดยไม่ต้องสแกนส่วนที่เหลือของไฟล์ ส่งรายชื่อคอลัมน์ไปยังพารามิเตอร์ columns หากตารางที่มี 100 คอลัมน์มีข้อมูลคอลัมน์ละ 100 MB และคุณต้องการเพียง 3 คอลัมน์ Parquet จะอ่านข้อมูล 3 MB แทนที่จะอ่าน 10 GB ส่วน CSV ต้องสแกนอักขระทุกตัวเพื่อดึงคอลัมน์ใด ๆ ออกมา จึงทำให้ Parquet เหมาะอย่างยิ่งกับตารางที่มีหลายคอลัมน์ในกระบวนการวิเคราะห์ข้อมูล

import pandas as pd

# Only load the 2 columns needed for this analysis
df = pd.read_parquet('large_table.parquet',
                     columns=['date', 'revenue'])
print(df.columns.tolist())
print(df.shape)
print(df.memory_usage(deep=True).sum() / 1e6, 'MB loaded')

การกรองกลุ่มแถว (การผลักเงื่อนไขลงไปยังแหล่งข้อมูล)

Parquet จะจัดเก็บสถิติ (ค่าต่ำสุด/สูงสุด) ของกลุ่มแถวแต่ละกลุ่ม (บล็อกของแถว) ไว้ในส่วนท้ายของไฟล์ เมื่อคุณใช้ตัวกรองผ่านพารามิเตอร์ filters ตัวอ่านจะข้ามกลุ่มแถวทั้งหมดที่ตัวกรองไม่สามารถตรงกันได้ — กระบวนการนี้เรียกว่าการผลักเงื่อนไขลงไปยังแหล่งข้อมูล ตัวอย่างเช่น การกรองวันที่ในไฟล์ Parquet ที่เรียงตามเวลาจะข้ามบล็อกของเดือนที่อยู่นอกช่วงทั้งหมด และอ่านเฉพาะส่วนที่เกี่ยวข้อง กลไก pyarrow รองรับความสามารถนี้โดยตรง

import pandas as pd

# Filter using predicate pushdown — row groups outside range are skipped
df = pd.read_parquet(
    'time_series.parquet',
    columns=['date', 'value'],
    filters=[('date', '>=', '2024-06-01'),
              ('date', '<', '2024-07-01')]
)
print(f'Loaded {len(df):,} rows (June only)')
print(df.head())

Parquet เทียบกับ CSV: การเปรียบเทียบ

ต่อไปนี้คือการเปรียบเทียบเชิงปฏิบัติระหว่าง Parquet กับ CSV สำหรับชุดข้อมูล 10 ล้านแถว 20 คอลัมน์:

  • ขนาดไฟล์: CSV ประมาณ 2 GB, Parquet (snappy) ประมาณ 400 MB
  • เวลาอ่าน (ทุกคอลัมน์): CSV ประมาณ 15 วินาที, Parquet ประมาณ 2 วินาที
  • เวลาอ่าน (3 คอลัมน์): CSV ประมาณ 15 วินาที (ต้องสแกนทั้งหมด), Parquet ประมาณ 0.3 วินาที
  • การรักษาชนิดข้อมูล: CSV สูญเสียชนิดข้อมูล, Parquet รักษาชนิดข้อมูลไว้
  • มนุษย์อ่านได้: CSV อ่านได้, Parquet อ่านไม่ได้ (เป็นไบนารี)

สำหรับกระบวนการประมวลผลข้อมูลที่ใช้งานจริง ซึ่งเขียนข้อมูลครั้งเดียวแต่อ่านหลายครั้ง Parquet มักเป็นตัวเลือกที่ดีกว่าเกือบเสมอ

ชุดข้อมูล Parquet แบบแบ่งพาร์ติชัน

สำหรับชุดข้อมูลขนาดใหญ่มาก Parquet รองรับชุดข้อมูลแบบแบ่งพาร์ติชัน: ข้อมูลจะถูกแบ่งเป็นหลายไฟล์และจัดระเบียบในลำดับชั้นของไดเรกทอรีตามค่าของคอลัมน์ ตัวอย่างเช่น การแบ่งตามปีและเดือนจะสร้าง data/year=2024/month=01/part.parquet การอ่านชุดข้อมูลแบบแบ่งพาร์ติชันจะกรองไดเรกทอรีที่ตรงกับคำสืบค้นโดยอัตโนมัติ นี่คือโครงสร้างมาตรฐานในคลังข้อมูล และช่วยให้สืบค้นช่วงข้อมูลจากหลายพันล้านแถวได้อย่างมีประสิทธิภาพ

import pandas as pd

# Write a partitioned dataset (requires pyarrow)
df = pd.read_parquet('all_data.parquet')
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month

df.to_parquet(
    'partitioned_data/',
    partition_cols=['year', 'month'],
    index=False
)
# Creates: partitioned_data/year=2024/month=1/part-0.parquet etc.

การอ่านชุดข้อมูลแบบแบ่งพาร์ติชัน

การอ่านไดเรกทอรี Parquet แบบแบ่งพาร์ติชันเหมือนกับการอ่านไฟล์เดียว — Pandas (ผ่าน pyarrow) จะค้นหาไฟล์พาร์ติชันทั้งหมดโดยอัตโนมัติ ค่าของคอลัมน์พาร์ติชันจะถูกรวมเป็นคอลัมน์ใน DataFrame ผลลัพธ์ คุณยังสามารถใช้ filters เพื่อใช้ประโยชน์จากการลดพาร์ติชัน โดยจะข้ามโครงสร้างไดเรกทอรีย่อยทั้งหมดตามค่าของคอลัมน์พาร์ติชัน ทำให้การสืบค้นชุดข้อมูลขนาด 1 TB ที่แบ่งพาร์ติชันให้ความรู้สึกราวกับกำลังอ่านข้อมูลเพียงไม่กี่ MB

import pandas as pd

# Read the entire partitioned dataset
df_all = pd.read_parquet('partitioned_data/')
print('All years:', df_all['year'].unique())

# Read only 2024 data using partition pruning
df_2024 = pd.read_parquet(
    'partitioned_data/',
    filters=[('year', '==', 2024)]
)
print('2024 rows:', len(df_2024))

Parquet กับ Dask

Dask สามารถอ่านและเขียน Parquet ได้โดยตรงด้วย dd.read_parquet() และ ddf.to_parquet() ไฟล์แต่ละไฟล์ในไดเรกทอรี Parquet แบบแบ่งพาร์ติชันจะกลายเป็นพาร์ติชัน Dask หนึ่งพาร์ติชัน ทำให้สามารถอ่านข้อมูลแบบขนานได้อย่างเต็มที่ Dask ยังใช้ประโยชน์จากการผลักเงื่อนไขลงไปยังแหล่งข้อมูลเมื่อระบุตัวกรอง การเขียนผลลัพธ์ Dask ขนาดใหญ่ลงในชุดข้อมูล Parquet แบบแบ่งพาร์ติชันเป็นวิธีมาตรฐานในการสร้างผลลัพธ์ในกระบวนการวิศวกรรมข้อมูลสมัยใหม่

import dask.dataframe as dd

# Read partitioned Parquet with Dask (each file = one partition)
ddf = dd.read_parquet('partitioned_data/',
                      columns=['date', 'revenue', 'region'],
                      filters=[('year', '==', 2024)])

# Compute aggregation in parallel
result = ddf.groupby('region')['revenue'].sum().compute()
print(result.sort_values(ascending=False))

ตัวเลือกการบีบอัดและการเข้ารหัส

Parquet รองรับอัลกอริทึมการบีบอัดและรูปแบบการเข้ารหัสภายในหลายแบบ Snappy (ค่าเริ่มต้น) เน้นความเร็วและให้การบีบอัดในระดับปานกลาง Gzip ทำให้ไฟล์มีขนาดเล็กลงประมาณ 30% แต่ใช้เวลาอ่านและเขียนนานกว่า Zstd สร้างสมดุลระหว่างความเร็วและการบีบอัดได้ดีกว่าทั้งสองแบบ สำหรับคอลัมน์จำนวนเต็ม Parquet จะใช้ delta encoding หรือ dictionary encoding โดยอัตโนมัติ เพื่อลดขนาดเพิ่มเติมโดยที่คุณไม่ต้องตั้งค่าใด ๆ

import pandas as pd
import numpy as np

np.random.seed(0)
df = pd.DataFrame({'id': range(500000), 'val': np.random.randn(500000)})

for comp in ['snappy', 'gzip', 'zstd']:
    fname = f'data_{comp}.parquet'
    df.to_parquet(fname, compression=comp, index=False)
    import os
    size_mb = os.path.getsize(fname) / 1e6
    print(f'{comp}: {size_mb:.2f} MB')

แทนที่ CSV ในไปป์ไลน์ของคุณ

วิธีที่ง่ายที่สุดในการเริ่มใช้ Parquet คือเพิ่ม ขั้นตอนการแปลงครั้งเดียว ไว้ตอนเริ่มโครงการ: อ่าน CSV ของคุณหนึ่งครั้ง ทำความสะอาดข้อมูลและกำหนดชนิดข้อมูล จากนั้นบันทึกเป็น Parquet การทำงานครั้งต่อ ๆ ไปจะอ่านไฟล์ Parquet แทน CSV วิธีนี้ช่วยให้ได้ประโยชน์ด้านความเร็วและพื้นที่จัดเก็บทันที โดยต้องแก้ไขโค้ดเพียงเล็กน้อย หากมีข้อมูลใหม่เข้ามาในรูปแบบ CSV (เช่น ไฟล์ส่งออกประจำคืน) ให้เพิ่มขั้นตอนการแปลงในไปป์ไลน์เพื่อเขียนเป็น Parquet ก่อนเริ่มการวิเคราะห์

import pandas as pd

# One-time conversion
df = pd.read_csv('raw_data.csv',
                 parse_dates=['date'],
                 dtype={'category': 'category',
                        'amount': 'float32'})
df.to_parquet('clean_data.parquet', index=False)

# All future reads use Parquet
df_fast = pd.read_parquet('clean_data.parquet')
print('Loaded from Parquet:', df_fast.dtypes.to_dict())

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจแนวคิดการวิเคราะห์ข้อมูลจากบทเรียนนี้

ทบทวนบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า to_parquet() และ read_parquet() ช่วยให้การอ่านและเขียนไฟล์เร็วขึ้น ไฟล์มีขนาดเล็กลง และรักษาชนิดข้อมูลได้ดีกว่า CSV, การเลือกเฉพาะคอลัมน์ ด้วยพารามิเตอร์ columns จะอ่านเฉพาะคอลัมน์ที่จำเป็น จึงไม่ต้องสแกนไฟล์ทั้งหมด และ ชุดข้อมูล Parquet แบบแบ่งพาร์ติชัน ที่จัดระเบียบตามค่าของคอลัมน์จะช่วยให้ตัดพาร์ติชันที่ไม่เกี่ยวข้องออกได้ ทำให้การค้นหาช่วงข้อมูลในคลังข้อมูลขนาดใหญ่มีประสิทธิภาพมากขึ้น บทถัดไป เราจะเชื่อมต่อ Pandas กับฐานข้อมูลเชิงสัมพันธ์โดยใช้ SQLAlchemy

คำถามที่พบบ่อย

บทเรียน “Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง”

เขียน Pandas DataFrame เป็น Parquet ด้วย to_parquet() อ่านกลับได้เร็วกว่าการใช้ CSV และใช้การเลือกเฉพาะคอลัมน์เพื่อโหลดเฉพาะฟิลด์ที่จำเป็น คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม

ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสตรีม CSV ด้วย chunksize
  2. การรวมค่าแบบเพิ่มทีละส่วนระหว่างชิ้นข้อมูล
  3. บทนำสู่ Dask DataFrames
  4. Parquet: การจัดเก็บข้อมูลแบบคอลัมน์ความเร็วสูง
← กลับไปที่ Pandas & NumPy Academy