Pandas read_csv() ใน Python พร้อมตัวอย่าง

⚡ สรุปอย่างชาญฉลาด

ฟังก์ชัน read_csv() ของ Pandas แปลงไฟล์ CSV ที่คั่นด้วยเครื่องหมายจุลภาค ไม่ว่าจะเป็นไฟล์ในเครื่องหรือไฟล์บนเซิร์ฟเวอร์ ให้เป็น DataFrame ได้ในการเรียกใช้เพียงครั้งเดียว ตัวอย่างนี้จะนำเข้าชุดข้อมูลสำมะโนประชากรผู้ใหญ่ของ UCI ตั้งชื่อคอลัมน์ทั้งสิบห้าคอลัมน์ และสรุปผลลัพธ์ด้วยการรวมกลุ่มแบบ groupby

  • 🔘 โทรเพียงครั้งเดียว: ฟังก์ชัน pd.read_csv() รับพาธไฟล์และพารามิเตอร์ต่างๆ URLหรือวัตถุใดๆ ที่มีเมธอดสำหรับอ่านข้อมูล
  • ☑️ การควบคุมคอลัมน์: ส่งชื่อเพื่อกำหนดป้ายกำกับคอลัมน์ และตั้งค่า index_col=False เพื่อใช้ดัชนีจำนวนเต็มธรรมดา
  • ช่องว่าง: skipinitialspace=True จะลบช่องว่างที่อยู่หลังเครื่องหมายจุลภาคทุกตัวในชุดข้อมูลผู้ใหญ่
  • 🧪 จัดกลุ่มและรวมข้อมูล: groupby() สรุปข้อมูลในเฟรมด้วยจำนวน, ค่าต่ำสุด, ค่าสูงสุด, ค่าเฉลี่ย, ค่ามัธยฐาน หรือค่าเบี่ยงเบนมาตรฐาน
  • 🛠️ ไฟล์ขนาดใหญ่: คำสั่ง usecols, dtype และ chunksize ช่วยลดเวลาในการแยกวิเคราะห์และใช้หน่วยความจำในการส่งออกข้อมูลขนาดหลายกิกะไบต์
  • ⚠️ ข้อผิดพลาดทั่วไป: การเข้ารหัส บรรทัดที่ไม่ถูกต้อง และประเภทข้อมูลที่ไม่ตรงกัน ต่างก็มีอาร์กิวเมนต์ที่ระบุไว้ในเอกสารซึ่งช่วยแก้ไขปัญหาเหล่านั้นได้

Pandas read_csv() พร้อมตัวอย่าง

นำเข้า CSV ใน Pandas

ในระหว่างบทเรียน TensorFlow คุณจะใช้ ชุดข้อมูลผู้ใหญ่ซึ่งมักใช้สำหรับงานจำแนกประเภท ไฟล์ที่ใช้ด้านล่างนี้เป็นไฟล์ดิบ adult.data ส่งออกข้อมูลจาก UCI Machine Learning Repository และหน้าข้อมูลชุดข้อมูลยังมีไฟล์ให้ดาวน์โหลดในรูปแบบไฟล์ซิปอีกด้วย ucimlrepo แพ็คเกจหากเส้นทางตรงหยุดทำงานเมื่อใด

ข้อมูลถูกจัดเก็บในรูปแบบ CSV ชุดข้อมูลประกอบด้วยตัวแปรเชิงหมวดหมู่ 8 ตัว:

  • ชั้นเรียน
  • การศึกษา
  • สมรส
  • อาชีพ
  • ความสัมพันธ์
  • แข่ง
  • เพศ
  • พื้นเมือง_ประเทศ

และตัวแปรต่อเนื่อง 6 ตัว:

  • อายุ
  • Fnlwgt
  • การศึกษา_num
  • ทุน_กำไร
  • เงินทุน_ขาดทุน
  • ชั่วโมง_สัปดาห์

พร้อมกับรายได้ label คอลัมน์ ซึ่งจะทำให้ได้ชื่อคอลัมน์ทั้ง 15 ชื่อที่คุณจะส่งต่อไปยัง นุ่น ในส่วนถัดไป

วิธี Pandas read_csv()

ในการนำเข้าชุดข้อมูล CSV คุณสามารถใช้เมธอด pd.read_csv() ได้ โดยมีรูปแบบการใช้งานพื้นฐานดังนี้:

Pandas read_csv() ไวยากรณ์

pandas.read_csv(filepath_or_buffer, sep=',', names=None, index_col=None, skipinitialspace=False)
  • เส้นทางไฟล์หรือบัฟเฟอร์: เส้นทาง, URLหรือวัตถุที่มีลักษณะคล้ายไฟล์ซึ่งเก็บข้อมูลไว้
  • sep=',': ตัวคั่นที่จะใช้
  • ชื่อ=ไม่มีระบุชื่อคอลัมน์ หากชุดข้อมูลมีสิบคอลัมน์ คุณต้องระบุชื่อสิบชื่อ
  • ดัชนี_คอลัมน์=ไม่มี: คอลัมน์ที่จะใช้เป็นดัชนีแถว ส่งค่า False เพื่อบังคับให้ใช้ดัชนีจำนวนเต็มใหม่
  • ข้ามช่องว่างเริ่มต้น=เท็จ: เว้นช่องว่างหลังตัวคั่น

สำหรับรายชื่อข้อโต้แย้งทั้งหมด โปรดตรวจสอบเอกสารอย่างเป็นทางการ เอกสารประกอบการใช้งาน pandas.read_csv().

Pandas read_csv() ตัวอย่าง

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

## Import csv
import pandas as pd
## Define path data
COLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital',
           'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss',
           'hours_week', 'native_country', 'label']
PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
df_train = pd.read_csv(PATH,
                       skipinitialspace=True,
                       names = COLUMNS,
                       index_col=False)
df_train.shape

Output:

(32561, 15)

โครงสร้างข้อมูลยืนยันว่ามี 32,561 แถวและ 15 คอลัมน์ ดังนั้นชื่อทุกชื่อใน COLUMNS จึงตรงกับฟิลด์ในไฟล์

พารามิเตอร์ของฟังก์ชัน read_csv() ใน Pandas

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

พารามิเตอร์ ค่าเริ่มต้น สิ่งที่มันไม่
กันยายน '' อักขระหรือนิพจน์ปกติที่ใช้เป็นตัวคั่น ใช้ sep=';' หรือ sep='\t' สำหรับรูปแบบอื่นๆ
ส่วนหัว 'อนุมาน' หมายเลขแถวที่เก็บป้ายกำกับคอลัมน์ ส่งค่า header=None เมื่อไฟล์ไม่มีแถวส่วนหัว
ชื่อ ไม่ได้ตั้งค่า ระบุป้ายกำกับคอลัมน์อย่างชัดเจน ใช้ร่วมกับ header=0 เพื่อแทนที่ส่วนหัวที่มีอยู่เดิม
ดัชนี_คอลัมน์ ไม่มี คอลัมน์ที่จะใช้เป็นดัชนีแถว index_col=False จะบังคับใช้ดัชนีเป็นจำนวนเต็มธรรมดา
ยูเซคอลส์ ไม่มี เลือกโหลดเฉพาะคอลัมน์ย่อยตามป้ายกำกับหรือตำแหน่ง ช่วยลดทั้งเวลาในการประมวลผลและหน่วยความจำ
ประเภท ไม่มี ประเภทข้อมูลต่อคอลัมน์ เช่น {'age': 'int32'} จะข้ามขั้นตอนการอนุมานประเภทข้อมูล
ค่า na ไม่มี สตริงเพิ่มเติมที่จะอ่านเป็นค่า NaN เช่น ตัวยึดตำแหน่ง '?' ในชุดข้อมูลผู้ใหญ่
ข้ามแถว / nแถว ไม่มี ข้ามบรรทัดนำหน้า หรืออ่านเฉพาะข้อมูล 9 แถวแรกเท่านั้น
การแยกวิเคราะห์วันที่ ไม่มี คอลัมน์ที่จะแปลงเป็นรูปแบบวันที่และเวลาขณะอ่าน โดยจับคู่กับรูปแบบวันที่
การเข้ารหัส 'utf-8' การเข้ารหัสข้อความของไฟล์ ใช้ 'latin-1' หรือ 'cp1252' สำหรับการส่งออกไฟล์แบบเก่า
ขนาดก้อน ไม่มี ส่งคืนตัววนซ้ำที่ส่งออกไฟล์เป็นบล็อกละ N แถว
บน_เส้นที่ไม่ดี 'ข้อผิดพลาด' ควรจัดการกับแถวที่ผิดรูปอย่างไร: ยกแถวขึ้น แจ้งเตือน หรือข้ามแถวนั้นไป

มีสองประเด็นที่ควรกล่าวถึงเป็นพิเศษ index_col=False การตั้งค่านี้ไม่เหมือนกับการปล่อยให้ว่างไว้: มันบอก Pandas อย่างชัดเจนว่าอย่าเลื่อนระดับคอลัมน์แรก ซึ่งเป็นสิ่งที่คุณต้องการเมื่อไฟล์ลงท้ายทุกบรรทัดด้วยตัวคั่นที่ไม่พึงประสงค์ และ names มันจะเขียนทับสิ่งที่ไฟล์ประกาศไว้โดยไม่แจ้งให้ทราบ ดังนั้นให้ส่งผ่าน header=0 นอกจากนี้แล้ว ไฟล์ CSV นั้นยังมีแถวส่วนหัวอยู่ด้วย

Pandas groupby () วิธีการ

วิธีง่ายๆ ในการดูข้อมูลคือการใช้เมธอด groupby เมธอดนี้ช่วยให้คุณสรุปข้อมูลตามกลุ่มได้ ด้านล่างนี้คือรายการการรวมข้อมูลที่มีให้ใช้งานกับเมธอด groupby():

  • นับ: นับ
  • นาที: นาที
  • สูงสุด: สูงสุด
  • หมายความว่า: หมายความว่า
  • มัธยฐาน: มัธยฐาน
  • ส่วนเบี่ยงเบนมาตรฐาน: std
  • และคนอื่น ๆ

ภายในฟังก์ชัน groupby() คุณจะต้องระบุชื่อคอลัมน์ที่คุณต้องการใช้จัดกลุ่มก่อนที่จะนำการรวมข้อมูลไปใช้

ลองมาดูกลุ่มหนึ่งกลุ่มกันping โดยใช้ชุดข้อมูลผู้ใหญ่ คุณจะได้รับค่าเฉลี่ยของตัวแปรต่อเนื่องทั้งหมดตามประเภทของรายได้ นั่นคือ มากกว่า 50 หรือน้อยกว่า 50:

df_train.groupby(['label']).mean()
ฉลาก อายุ Fnlwgt การศึกษา_num ทุน_กำไร เงินทุน_ขาดทุน ชั่วโมง_สัปดาห์
<=50K 36.783738 190340.86517 9.595065 148.752468 53.142921 38.840210
> 50K 44.249841 188005.00000 11.611657 4006.142456 195.001530 45.473026

คุณสามารถตรวจสอบอายุขั้นต่ำตามประเภทของครัวเรือนได้:

df_train.groupby(['label'])['age'].min()
label
<=50K    17
>50K     19
Name: age, dtype: int64

คุณสามารถจัดกลุ่มตามคอลัมน์ต่างๆ ได้ ตัวอย่างเช่น คุณสามารถรับกำไรจากการลงทุนสูงสุดตามประเภทครัวเรือนและสถานะการสมรส

df_train.groupby(['label', 'marital'])['capital_gain'].max()
label  marital
<=50K  Divorced                 34095
       Married-AF-spouse         2653
       Married-civ-spouse       41310
       Married-spouse-absent     6849
       Never-married            34095
       Separated                 7443
       Widowed                   6849
>50K   Divorced                 99999
       Married-AF-spouse         7298
       Married-civ-spouse       99999
       Married-spouse-absent    99999
       Never-married            99999
       Separated                99999
       Widowed                  99999
Name: capital_gain, dtype: int64

คุณสามารถสร้างกราฟหลังจากการจัดกลุ่มได้ วิธีหนึ่งคือการสร้างกราฟของผลลัพธ์ที่จัดกลุ่มแล้วโดยตรง

เพื่อให้ได้กราฟที่ชัดเจนยิ่งขึ้น ให้ใช้ unstack() หลัง mean() เพื่อให้สถานะการสมรสย้ายจากดัชนีไปอยู่ในคอลัมน์ จากนั้นกราฟจะมีสองกลุ่ม กลุ่มละหนึ่งระดับรายได้ แทนที่จะเป็นแท่งกราฟสิบสี่แท่ง (2*7) เหมือนกับดัชนีหลายระดับแบบแบนราบ

หากคุณใช้ Jupyter สมุดบันทึกอย่าลืมเพิ่ม %matplotlib ในบรรทัด มิฉะนั้นกราฟจะไม่แสดง

%matplotlib inline
df_plot = df_train.groupby(['label', 'marital'])['capital_gain'].mean().unstack()
df_plot

การนำเฟรมที่ไม่ซ้อนกันนั้นมาแสดงเป็นแผนภูมิแท่งจะได้ภาพดังด้านล่าง

แผนภูมิแท่งแสดงค่าเฉลี่ยกำไรจากการลงทุนจำแนกตามระดับรายได้และสถานภาพการสมรส

วิธีการอ่านไฟล์ CSV ขนาดใหญ่ด้วย Pandas

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

  • ยูเซคอลส์ โหลดเฉพาะคอลัมน์ที่คุณต้องการจริงๆ เท่านั้น เอกสารของ pandas ระบุว่าวิธีนี้จะทำให้การวิเคราะห์ข้อมูลเร็วขึ้นและใช้หน่วยความจำน้อยลงมาก
  • ประเภท ฟังก์ชันนี้จะกำหนดประเภทให้กับแต่ละคอลัมน์ ทำให้ Pandas ข้ามขั้นตอนการอนุมานประเภทและไม่ขยายจำนวนเต็มเป็น 64 บิตโดยค่าเริ่มต้น
  • ขนาดก้อน ฟังก์ชันนี้จะส่งคืน TextFileReader แทนที่จะเป็น DataFrame ทำให้คุณสามารถวนลูปผ่านบล็อกของแถว N แถวและรวมผลลัพธ์ไปพร้อมกันได้
import pandas as pd

# read only the columns you need, with explicit types
cols  = ['age', 'education', 'capital_gain', 'label']
types = {'age': 'int32', 'capital_gain': 'int32'}
df = pd.read_csv(PATH, names=COLUMNS, usecols=cols, dtype=types,
                 skipinitialspace=True, index_col=False)

# stream the file in fixed-size chunks instead of loading it whole
total = 0
for chunk in pd.read_csv(PATH, names=COLUMNS, chunksize=10000,
                         skipinitialspace=True, index_col=False):
    total = total + len(chunk)
print(total)

เมื่อวางรากฐานพื้นฐานเสร็จแล้ว ยังมีอีกสองทางเลือกเพิ่มเติมที่จะช่วยได้ engine='pyarrow' เปลี่ยนไปใช้ตัวแยกวิเคราะห์ Arrow แบบมัลติเธรด และ dtype_backend='pyarrow' แสดงผลลัพธ์ในรูปแบบคอลัมน์ที่มีลูกศรชี้ low_memory ค่าเริ่มต้นคือ True ซึ่งจะทำการแยกวิเคราะห์ไฟล์ภายในเป็นส่วนๆ แต่ผลลัพธ์ที่ได้อาจเป็นประเภทข้อมูลที่แตกต่างกันในคอลัมน์เดียว ดังนั้นควรกำหนด dtype อย่างชัดเจนแทนที่จะพึ่งพาค่าเริ่มต้นนี้

ในที่สุด compression='infer' หมายความว่าไฟล์ที่มีนามสกุล .gz, .zip, .bz2, .xz หรือ .zst จะถูกคลายการบีบอัดโดยอัตโนมัติ ดังนั้นจึงไม่จำเป็นต้องแตกไฟล์ก่อนที่จะอ่านไฟล์นั้น

ข้อผิดพลาดทั่วไปของการใช้ฟังก์ชัน read_csv() ใน Pandas และวิธีแก้ไข

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

ความผิดพลาด ก่อให้เกิด แก้ไขปัญหา
FileNotFoundError เส้นทางดังกล่าวสัมพันธ์กับไดเร็กทอรีการทำงาน ไม่ใช่กับสคริปต์ ใช้พาธแบบสัมบูรณ์ หรือตรวจสอบความถูกต้อง URL รูปแบบการจัดเก็บข้อมูลคืออย่างใดอย่างหนึ่งต่อไปนี้: http, ftp, s3, gs หรือ file
UnicodeDecodeError ไฟล์นี้ไม่ได้ใช้การเข้ารหัส UTF-8 ซึ่งเป็นการเข้ารหัสเริ่มต้น ส่งค่า encoding='latin-1' หรือ codec ที่ถูกต้อง หรือ encoding_errors='replace'
ParserError: เกิดข้อผิดพลาดในการแยกข้อมูลเป็นโทเค็น แต่ละแถวจะมีฟิลด์มากกว่าที่ระบุไว้ในส่วนหัว ส่งค่า on_bad_lines='skip' หรือ 'warn' หรือตั้งค่า sep ให้ถูกต้อง
DtypeWarning: คอลัมน์มีชนิดข้อมูลผสมกัน การอนุมานประเภทแบบแบ่งกลุ่มทำให้เห็นประเภทต่างๆ ในคอลัมน์เดียวกัน ระบุชนิดข้อมูล (dtype) อย่างชัดเจน หรือตั้งค่า low_memory=False
คอลัมน์เลื่อนไปหนึ่งตำแหน่ง ตัวคั่นท้ายจะทำให้ Pandas เลื่อนฟิลด์แรกขึ้นไปอยู่ในดัชนี ส่งค่า index_col=False

ชุดข้อมูลสำหรับผู้ใหญ่แสดงกรณีค่าที่หายไปโดยตรง: ค่า workclass, occupation และ native_country ที่ไม่ทราบจะถูกจัดเก็บเป็นเครื่องหมายคำถาม (?) เว้นแต่คุณจะระบุค่าเหล่านั้นไว้

# tolerate rows with too many fields instead of raising
df = pd.read_csv(PATH, names=COLUMNS, on_bad_lines='skip')

# read a file that is not UTF-8
df = pd.read_csv('sales.csv', encoding='latin-1')

# treat the dataset's '?' placeholder as a missing value
df = pd.read_csv(PATH, names=COLUMNS, na_values='?', skipinitialspace=True)

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

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

เรียกใช้ df.to_csv('output.csv', index=False) แล้วลบทิ้งping ดัชนีจะหลีกเลี่ยงคอลัมน์แรกที่ไม่มีชื่อในการอ่านครั้งถัดไป เพิ่มอาร์กิวเมนต์ sep, encoding หรือ compression เพื่อให้ตรงกับการตั้งค่าที่คุณใช้เมื่อนำเข้าไฟล์

ส่งพารามิเตอร์ parse_dates พร้อมชื่อคอลัมน์หรือตำแหน่ง และเพิ่ม date_format เมื่อรูปแบบไม่ใช่ ISO 8601 ตัวอย่างเช่น date_format='%d/%m/%Y' หากไม่มีพารามิเตอร์นี้ คอลัมน์วันที่จะถูกส่งมาในรูปแบบสตริงออบเจ็กต์ธรรมดา และต้องเรียกใช้ฟังก์ชัน to_datetime แยกต่างหาก

กำหนดค่า sep เป็นอักขระ เช่น sep=';' หรือ sep='\t' ตัวคั่นที่ยาวกว่าหนึ่งอักขระจะถูกมองว่าเป็นนิพจน์ปกติและบังคับให้ประมวลผลช้าลง Python engine.sep=None อนุญาตให้เอนจินตรวจจับตัวคั่นจากแถวแรกที่ถูกต้อง

ใช้ nrows เพื่อจำกัดจำนวนแถวข้อมูลที่ส่งคืน และใช้ skiprows เพื่อข้ามกลุ่มบรรทัดนำหน้า การรวมคำสั่งเหล่านี้เข้าด้วยกันจะช่วยแบ่งหน้าไฟล์ ตัวอย่างเช่น skiprows=1000000 ร่วมกับ nrows=999999 เพื่ออ่านแถวล้านแถวที่สอง

ใช่แล้ว การบีบอัดข้อมูลโดยค่าเริ่มต้นจะใช้โหมด 'infer' ดังนั้นไฟล์ที่มีนามสกุล .gz, .zip, .bz2, .xz หรือ .zst จะถูกคลายการบีบอัดโดยอัตโนมัติ URLการใช้ http, ftp, s3, gs หรือไฟล์ล้วนใช้งานได้ และ storage_options จะส่งข้อมูลรับรองไปยังแบ็กเอนด์ระยะไกล

โมเดลที่ผ่านการฝึกฝนจะระบุข้อผิดพลาดประเภทข้อมูลที่อาจเกิดขึ้น จัดกลุ่มการสะกดคำหมวดหมู่ที่ใกล้เคียงกัน และเติมค่าที่หายไปจากคอลัมน์โดยรอบ ซึ่งจะช่วยลดการแก้ไขด้วยตนเองให้เหลือเฉพาะแถวที่การตั้งค่า na_values ​​หรือ dtype ตามกฎไม่สามารถแก้ไขได้ด้วยตัวเอง

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

สรุปโพสต์นี้ด้วย: