ข้ามไปยังเนื้อหาหลัก

Polars read_csv(): โหลดข้อมูล CSV อย่างรวดเร็วใน Python

ค้นพบว่า Polars read_csv() ช่วยโหลดข้อมูล CSV ใน Python ได้อย่างมีประสิทธิภาพอย่างไร รวมถึงการจัดการชุดข้อมูลขนาดใหญ่ การกำหนดสคีมา และการเพิ่มประสิทธิภาพ
อัปเดตแล้ว 22 ก.ย. 2569  · 7 นาที อ่าน

สำรวจด้วย AI

ChatGPTClaudePerplexity

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

Polars คือไลบรารี DataFrame ที่ทันสมัยและรวดเร็วสำหรับ Python ออกแบบมาเป็นทางเลือกสมรรถนะสูงแทน Pandas จัดการชุดข้อมูลขนาดใหญ่ได้ลื่นไหลกว่ามาก เพราะสร้างขึ้นโดยมุ่งเน้นความเร็วและการใช้หน่วยความจำต่ำ

ฟังก์ชันหลักของ Polars pl.read_csv() ให้วิธีง่าย ๆ ในการโหลดไฟล์ CSV เข้าสู่ DataFrame พร้อมตัวเลือกในตัวเพื่อควบคุมการพาร์ส ชนิดข้อมูล และการใช้หน่วยความจำ

ในคู่มือนี้ จะแสดงวิธีการอ่านไฟล์ CSV ควบคุมการพาร์ส และจัดการชุดข้อมูลขนาดใหญ่ด้วยฟังก์ชัน  pl.read_csv() ของ Polars หากเพิ่งเริ่มต้น แนะนำคอร์ส Introduction to Polars เพื่อเรียนรู้การจัดการข้อมูลและสกัดอินไซต์ด้วย Polars

การใช้งานพื้นฐานของ pl.read_csv()

ก่อนจะไปต่อ ลองดูบทช่วยสอน Python Polars เพื่อเรียนรู้การตั้งค่าสภาพแวดล้อม

มาดูกันว่าฟังก์ชัน pl.read_csv() ทำงานอย่างไร: 

# import the module
import polars as pl

# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv")  

# Preview first few rows
print(fuel_data.head())  

ในตัวอย่างข้างต้น Polars จะอ่านไฟล์และโหลดเข้าเป็น DataFrame ฟังก์ชันจะส่งคืน Polars DataFrame ซึ่งเป็นโครงสร้างข้อมูลแบบตาราง คล้ายกับที่ได้ใน pandas

โดยค่าเริ่มต้น pl.read_csv():

  • ถือว่าแถวแรกเป็นชื่อตารางคอลัมน์ (has_header=True)

  • เดาชนิดข้อมูลของคอลัมน์โดยอัตโนมัติ

  • ใช้เครื่องหมายจุลภาค (,) เป็นตัวคั่น

  • อ่านทั้งไฟล์เข้าสู่หน่วยความจำ

พารามิเตอร์ที่พบบ่อยใน pl.read_csv()

เมื่อทราบแล้วว่า pl.read_csv() โหลดข้อมูลอย่างไร มาดูว่าพารามิเตอร์ต่อไปนี้ช่วยปรับวิธีที่ Polars พาร์สข้อมูลได้อย่างไร

พาธไฟล์และแหล่งข้อมูล

Polars อนุญาตให้โหลดข้อมูลจากแหล่งต่าง ๆ ได้ สามารถส่งพาธแบบสตริงภายในเครื่อง อ็อบเจ็กต์ Pathlib หรือแม้แต่ URL ตัวอย่างโค้ดต่อไปนี้อ่านไฟล์ csv ขนาดใหญ่จากเว็บ ที่มีข้อมูล GDP ของประเทศต่าง ๆ ในหลายปี

# Reading from a URL
url = "https://raw.githubusercontent.com/datasets/gdp/master/data/gdp.csv"
gdp_data = pl.read_csv(url)

ตัวคั่นและตัวแยก

ไม่ใช่ทุกไฟล์ CSV จะใช้จุลภาค สามารถใช้พารามิเตอร์ separator เพื่อรองรับแท็บ เซมิโคลอน ไพพ์ หรืออักขระอื่น ๆ ตัวอย่างด้านล่างแสดงวิธีกำหนดตัวคั่นเมื่ออ่านไฟล์

# Reading a Semicolon-separated file
sales_data = pl.read_csv("2024_sales.csv", separator=";")

# Reading a Tab-separated file (TSV)
orders_data = pl.read_csv("all_orders.tsv", separator="\t")

การจัดการเฮดเดอร์

ดังที่เห็นก่อนหน้า Polars จะถือว่าแถวแรกของข้อมูลเป็นชื่อคอลัมน์ หากไฟล์ไม่มีแถวเฮดเดอร์ ให้ใช้พารามิเตอร์ has_header=False ตามด้านล่าง Polars จะกำหนดชื่อคอลัมน์ให้โดยอัตโนมัติ เช่น column_1, column_2, column_3 เป็นต้น

# Load file without a header
orders_data = pl.read_csv("all_orders.csv", has_header=False)

ยังสามารถเปลี่ยนชื่อคอลัมน์โดยระบุชื่อคอลัมน์ที่ต้องการได้ เช่น:

# Providing specific column names
sales_data = pl.read_csv("sales_April.csv", new_columns=[
    "OrderDate", "OrderNumber", "ProductKey", "SalespersonKey", "Salesperson"])

การเข้ารหัสอักขระ

ไฟล์ CSV อาจใช้การเข้ารหัสข้อความต่างกัน หากพบอักขระประหลาดหรือข้อผิดพลาด ให้ระบุการเข้ารหัส:

# Load CSV into a Polars DataFrame
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv", encoding="utf8")  

ตัวเลือกการเข้ารหัสที่พบบ่อยอื่น ๆ ได้แก่ ”latin1” และ ”utf8-lossy” ซึ่งรองรับอักขระไม่ถูกต้องได้เหมาะสม

วิธีเลือกคอลัมน์ขณะอ่าน CSV ใน Polars

เมื่อทำงานกับไฟล์ CSV ขนาดใหญ่ มักไม่จำเป็นต้องใช้ทุกคอลัมน์ Polars อนุญาตให้โหลดเฉพาะคอลัมน์ที่ต้องการด้วยพารามิเตอร์ columns

# Load only specific columns
fuel_data = pl.read_csv("Fuel_Consumption_2000-2022.csv",
    columns=["YEAR", "MAKE", "MODEL"]
)

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

วิธีจัดการชนิดข้อมูล (สคีมา) ใน Polars CSV

Polars เป็นไลบรารีที่มีการกำหนดชนิดข้อมูลอย่างเข้มงวด หมายความว่าทุกคอลัมน์ต้องมีชนิดข้อมูลที่สอดคล้องกัน เช่น ทั้งหมดเป็นจำนวนเต็มหรือทั้งหมดเป็นสตริง

การเดาชนิดข้อมูลอัตโนมัติ

โดยค่าเริ่มต้น Polars จะตรวจสอบข้อมูลและกำหนดชนิดคอลัมน์ให้อัตโนมัติ วิธีเริ่มต้นนี้ใช้ได้ดีในหลายกรณี แต่บางครั้งอาจตีความคอลัมน์ผิด เช่น มอง ID เป็นจำนวนเต็มแทนที่จะเป็นสตริง

การกำหนดสคีมาเอง

เมื่ออยากให้ DataFrame มีความสม่ำเสมอ ควรกำหนดสคีมาด้วยตนเอง วิธีนี้ทำให้สอดคล้องกันข้ามหลายไฟล์ และช่วยหลีกเลี่ยงข้อผิดพลาดที่เกี่ยวข้องกับชนิดข้อมูลในกระบวนการถัดไป

ในกรณีส่วนใหญ่ ให้ใช้ schema_overrides เพื่อระบุชนิดข้อมูลของคอลัมน์บางคอลัมน์ ขณะที่ปล่อยให้ Polars เดาที่เหลือ

import polars as pl

# Manually overriding specific data types
empl_data = pl.read_csv(
    "all_employees.csv",
    schema_overrides={
        "id": pl.Int64,
        "name": pl.String,
        "age": pl.Int64,
        "salary": pl.Float64
    }
)

หรือใช้ schema เพื่อกำหนดโครงสร้างของ DataFrame ทั้งหมด

# Manually define the full schema
empl_data = pl.read_csv(
    "all_employees.csv",
    schema={
        "id": pl.Int64,
        "name": pl.String,
        "age": pl.Int64,
        "salary": pl.Float64
    }
)

วิธีจัดการค่าที่ขาดหาย ใน Polars CSV

โดยค่าเริ่มต้น Polars จะตรวจจับค่าที่ขาดหายเหล่านี้และแสดงเป็น null บางครั้งค่าที่หายอาจแทนด้วยสตริงเฉพาะ เช่น ”NA”, ”N/A” หรือ ”missing” สามารถกำหนดได้ด้วย null_values เพื่อให้ถือเป็น null

# Treating "N/A" and "EMPTY" as nulls
survey_data = pl.read_csv(
    "survey_results.csv",
    null_values=["N/A", "EMPTY", "null"]
)

เมื่อจัดการค่าที่ขาดหายได้ถูกต้อง จะช่วยให้ชนิดข้อมูลสม่ำเสมอและป้องกันการคำนวณที่ผิดพลาด ลดข้อผิดพลาดระหว่างการวิเคราะห์และการสร้างแบบจำลอง

การอ่านไฟล์ CSV ขนาดใหญ่ใน Polars

เมื่อทำงานกับชุดข้อมูลขนาดใหญ่เกินหน่วยความจำ RAM ที่มี Polars โดดเด่นมากในการประมวลผลข้อมูลโดยไม่ต้องโหลดทั้งไฟล์ในคราวเดียว

Lazy Loading ด้วย scan_csv()

แทนที่จะโหลดข้อมูลเข้าหน่วยความจำทันทีแบบ read_csv() Polars มีทางเลือกแบบ lazy คือ scan_csv() ซึ่งสร้างแผนคำสั่งที่เหมาะสมและรันเฉพาะสิ่งที่จำเป็น

ในตัวอย่างด้านล่าง pl.scan_csv จะสแกนไฟล์ CSV โดยไม่โหลดมันขึ้นมา สร้างคิวรีเพื่อดึงเฉพาะคอลัมน์ “YEAR”, “MAKE” และ “MODEL” ที่ยี่ห้อรถเป็น “ACURA” แล้วจึงรันคิวรีนั้น การทำงานนี้จะโหลดเฉพาะส่วนข้อมูลที่กรองแล้วเข้าสู่หน่วยความจำ แทนที่จะโหลดทั้งไฟล์

# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")  

fuel_consumption_filtered = fuel_consumption.select(
    ["YEAR", "MAKE", "MODEL"]).filter(pl.col("MAKE") == "ACURA")

# Execute the query and load only the required data
fuel_consumption_acura = fuel_consumption_filtered.collect()  

แนะนำให้ใช้ scan_csv() เมื่อ:

  • ทำงานกับไฟล์ขนาดใหญ่ที่กินหน่วยความจำมากเกินไป
  • ใช้ทรานส์ฟอร์เมชันหลายขั้น เช่น การกรอง การเลือก และการจัดกลุ่มข้อมูล
  • ต้องการการปรับแต่งคิวรีให้เหมาะสมก่อนรัน

การสตรีมและประสิทธิภาพหน่วยความจำ

Polars ยังรองรับการสตรีมเพื่อประมวลผลข้อมูลเป็นชังก์ ๆ ทำให้หน่วยความจำพีกคงที่ไม่ว่าจะขนาดไฟล์เท่าใด

สำหรับไฟล์ CSV ขนาดใหญ่ เริ่มด้วย scan_csv() เพื่อสร้างคิวรีแบบ lazy เมื่อเรียก scan_csv() ไฟล์จะยังไม่ถูกโหลดเต็ม

# Read data in chunks
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv",
 low_memory=True)

เนื่องจากวิธีข้างต้นยังใช้ read_csv วิธีที่ดีที่สุดคือผสานการรันแบบ lazy เข้ากับการสตรีม

ในตัวอย่างด้านล่าง Polars ประมวลผลไฟล์แบบไปป์ไลน์ ทีละแบตช์ทีละแถว โดยเก็บเฉพาะแถวที่ผ่านการกรอง (“CYLINDERS” > 3) ไว้ในหน่วยความจำ ณ เวลาใดเวลาหนึ่ง

# Lazily reference the file (no data loaded yet)
fuel_consumption = pl.scan_csv("Fuel_Consumption_2000-2022.csv")  

result = fuel_consumption.filter(pl.col("CYLINDERS") > 3)

# Stream execution instead of loading everything at once
fuel_consumption_high = result.collect(engine="streaming")

ความได้เปรียบด้านประสิทธิภาพเมื่อเทียบกับ Pandas

เมื่อเทียบกับ pandas Polars มักทำงานได้ดีกว่าในการอ่านและประมวลผล CSV ดังที่จะเห็นในส่วนถัดไป

Polars read_csv เทียบกับ Pandas read_csv

ตารางด้านล่างสรุปความแตกต่างระหว่าง Polars และ Pandas เมื่ออ่าน csv ใน Python

ประเด็น

Polars

Pandas

ความเร็ว

เร็วกว่าเพราะมีมัลติเธรดและการพาร์สที่ปรับแต่ง

ช้ากว่าเมื่อไฟล์ใหญ่ (ส่วนใหญ่ทำงานแบบซิงเกิลเธรด)

การใช้หน่วยความจำ

ใช้ทรัพยากรต่ำ; รองรับแบบ lazy + สตรีมมิง

โหลดทั้งชุดข้อมูลเข้าสู่หน่วยความจำแบบ eager

ไวยากรณ์

pl.read_csv(“data.csv”)

pd.read_csv(“data.csv”)

โมเดลการรัน

รองรับการรันแบบ lazy (scan_csv)

รันแบบ eager (ทันที) เท่านั้น

การเพิ่มประสิทธิภาพ

มีการปรับแต่งคิวรีในตัว (projection, filtering)

มีการเพิ่มประสิทธิภาพอัตโนมัติจำกัด

กรณีใช้งานที่เหมาะสม

ชุดข้อมูลขนาดใหญ่ เวิร์กโฟลว์ที่ต้องการสมรรถนะสูง

ชุดข้อมูลขนาดเล็ก การวิเคราะห์อย่างรวดเร็ว

แนะนำให้อ่านบทความเกี่ยวกับความแตกต่างระหว่าง Pandas vs. Polars เพื่อพิจารณาว่าเครื่องมือใดเหมาะกับความต้องการเชิงวิเคราะห์มากที่สุด

การอ่าน CSV จากแหล่งต่าง ๆ

ดังที่เห็นก่อนหน้า สามารถใช้ Polars อ่านไฟล์ csv จากหลายแหล่ง ตัวอย่างด้านบนได้แสดงวิธีอ่านจากไฟล์ภายในเครื่องและ URL

นอกจากนี้ Polars จัดการไฟล์ CSV แบบบีบอัดได้อัตโนมัติ ตัวอย่างเช่น โค้ดต่อไปนี้อ่านข้อมูลจากไฟล์ .gzip

# Read gzip-compressed CSV
census_data = pl.read_csv("2018_census.csv.gz")

ข้อผิดพลาดที่พบบ่อยและการแก้ไขปัญหา

แม้จะใช้เอนจินสมรรถนะสูงอย่าง Polars ก็ยังอาจพบปัญหาได้ โดยเฉพาะตอนอ่านไฟล์ csv ต่อไปนี้คือปัญหาทั่วไปที่มักพบและแนวทางแก้ไข

  • ข้อผิดพลาดการเข้ารหัส: อาจพบข้อผิดพลาดอย่าง UnicodeDecodeError ซึ่งหมายความว่าไฟล์ไม่ได้ใช้การเข้ารหัส UTF-8 ปัญหานี้พบได้บ่อยในไฟล์เก่าหรือ CSV ที่ส่งออกจาก Excel บางเวอร์ชัน วิธีแก้คือกำหนดการเข้ารหัสให้ถูกต้อง หรือใช้ “utf8-lossy” หากไฟล์มีอักขระไม่สม่ำเสมอหรือเสียหาย

  • ปัญหาตัวคั่น: หาก DataFrame โหลดขึ้นมาแต่ข้อมูลไปกองอยู่คอลัมน์เดียว แสดงว่า Polars ไม่รู้จักตัวคั่น ให้แก้โดยกำหนดตัวคั่นที่ถูกต้องอย่างชัดเจนด้วยอาร์กิวเมนต์ separator เช่น เซมิโคลอน (;) แท็บ (\t) หรือไพพ์ (|)

  • ชนิดข้อมูลไม่ถูกต้อง: บางครั้ง Polars อาจเดาชนิดคอลัมน์ผิด เช่น อ่าน ID เชิงตัวเลขเป็นสตริง หรือพบข้อผิดพลาดการพาร์ส เมื่อเกิดเหตุการณ์นี้ สามารถใช้ schema_overrides เพื่อระบุชนิดข้อมูลของคอลัมน์เฉพาะ หากต้องการกำหนดชนิดให้ทุกคอลัมน์ให้ใช้ schema และยังสามารถเพิ่ม infer_schema_length เพื่อให้ Polars ตรวจสอบหลายแถวขึ้นก่อนเดาสคีมา

  • ปัญหาหน่วยความจำเมื่อไฟล์ใหญ่: หากโพรเซส Python ล่มเมื่อลองโหลดไฟล์ขนาดใหญ่ แปลว่า RAM ไม่พอ ให้สลับจาก read_csv() เป็น scan_csv() เพื่อโหลดแบบ lazy เพื่อลดการใช้หน่วยความจำและเพิ่มประสิทธิภาพ อาจโหลดคอลัมน์ให้น้อยลง หรือใช้การรันแบบสตรีมเพื่อนำเข้าข้อมูลเป็นชังก์

สรุป

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

ขั้นตอนถัดไป ลองอ่านบล็อกเกี่ยวกับ เอนจิน GPU ของ Polars เพื่อเรียนรู้การใช้งานต่าง ๆ และหากพร้อมลงมือปฏิบัติ Super Bowl Analytics with Polars แบบโค้ดตาม เพื่อแก้โจทย์วิเคราะห์จริง ทำการคำนวณ และประยุกต์เทคนิค ML พื้นฐานกับปัญหาวิเคราะห์ข้อมูลกีฬาได้

FAQs

ความแตกต่างระหว่าง read_csv() และ scan_csv() ใน Polars คืออะไร?

read_csv() โหลดข้อมูลเข้าสู่หน่วยความจำแบบ eager ในขณะที่ scan_csv() ใช้การรันแบบ lazy และจะประมวลผลข้อมูลก็ต่อเมื่อเรียก .collect()

ควรใช้ scan_csv() แทน read_csv() เมื่อใด?

ใช้ scan_csv() กับชุดข้อมูลขนาดใหญ่หรือเมื่อเชื่อมทรานส์ฟอร์เมชันหลายขั้น เพราะช่วยปรับแต่งการรันและลดการใช้หน่วยความจำ

Polars อ่านเฉพาะคอลัมน์บางคอลัมน์จากไฟล์ CSV ได้หรือไม่?

ได้ ใช้พารามิเตอร์ columns=[...] ใน read_csv() หรือเลือกคอลัมน์ในคิวรีแบบ lazy ด้วย scan_csv()

จะจัดการค่าที่ขาดหายในไฟล์ CSV ของ Polars อย่างไร?

Polars ถือว่าค่าว่างเป็น null ตามค่าเริ่มต้น และสามารถกำหนดเครื่องหมาย null แบบกำหนดเองด้วย null_values=

Polars รองรับไฟล์ CSV ที่บีบอัดหรือไม่?

ได้ รองรับฟอร์แมตแบบบีบอัดอย่าง .gz และ .zip โดยไม่ต้องแตกไฟล์เอง

หัวข้อ
Python

เรียนรู้ Polars กับ DataCamp

Courses

Introduction to Polars

3 ชม.
6.9K
เรียนรู้วิธีแปลง ทำความสะอาด และวิเคราะห์ข้อมูลอย่างมีประสิทธิภาพด้วย Polars ไลบรารี Python สำหรับจัดการข้อมูลความเร็วสูง
ดูรายละเอียดRight Arrow
เริ่มหลักสูตร
ดูเพิ่มเติมRight Arrow