การเติมค่าที่หายไป
แทนที่ NaN ด้วยค่าคงที่ ค่าเฉลี่ยของคอลัมน์ การเติมค่าจากด้านหน้า หรือการเติมค่าจากด้านหลัง โดยใช้ fillna() และพารามิเตอร์ method
การเติมค่าที่หายไป เป็นบทเรียน Pandas & NumPy Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Pandas & NumPy Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
บทนำสู่ fillna()
การแทนค่าที่หายไป หมายถึงการแทนค่าที่หายไปด้วยค่าทดแทนที่สมเหตุสมผล แทนที่จะลบแถวนั้น Pandas มี fillna() เป็นเครื่องมือหลักสำหรับงานนี้ โดยจะแทนที่ NaN ทุกค่าใน Series หรือ DataFrame ด้วยค่าที่คุณระบุ ต่างจากการลบ การแทนค่าที่หายไปจะรักษาทุกแถวไว้ ซึ่งสำคัญเป็นพิเศษเมื่อข้อมูลมีจำกัด หรือรูปแบบของข้อมูลที่หายไปมีความหมาย
รูปแบบที่ง่ายที่สุดคือการส่งค่าคงที่เข้าไป: df['col'].fillna(0)
import pandas as pd
import numpy as np
df = pd.DataFrame({
'product': ['A', 'B', 'C', 'D'],
'price': [10.0, np.nan, 30.0, np.nan]
})
# Fill all NaN in 'price' with 0
filled = df['price'].fillna(0)
print(filled)
# 0 10.0
# 1 0.0
# 2 30.0
# 3 0.0การเติมค่าด้วยค่าเฉลี่ยหรือค่ามัธยฐานของคอลัมน์
การเติมค่าด้วย mean ของคอลัมน์ (สำหรับการแจกแจงแบบสมมาตร) หรือ median (สำหรับการแจกแจงที่เบ้) เป็นหนึ่งในกลยุทธ์การแทนค่าที่ใช้กันมากที่สุด สถิติเหล่านี้สะท้อนแนวโน้มเข้าสู่ส่วนกลางของข้อมูล จึงช่วยลดการบิดเบือนการแจกแจงของคอลัมน์ได้ ควรคำนวณสถิติดังกล่าวจากชุดฝึกเสมอ เพื่อป้องกันการรั่วไหลของข้อมูล
import pandas as pd
import numpy as np
df = pd.DataFrame({
'salary': [50000, np.nan, 70000, 80000, np.nan, 60000]
})
mean_salary = df['salary'].mean()
median_salary = df['salary'].median()
df['salary_mean_filled'] = df['salary'].fillna(mean_salary)
df['salary_median_filled'] = df['salary'].fillna(median_salary)
print(df)
# salary salary_mean_filled salary_median_filled
# 0 50000.0 50000.0 50000.0
# 1 NaN 65000.0 65000.0
# 2 70000.0 70000.0 70000.0การเติมค่าข้อมูลเชิงหมวดหมู่ด้วยฐานนิยม
สำหรับ คอลัมน์เชิงหมวดหมู่ การเติมค่าด้วยค่าเฉลี่ยหรือค่ามัธยฐานไม่สมเหตุสมผล ควรใช้ mode ซึ่งก็คือค่าที่ปรากฏบ่อยที่สุดแทน Series.mode()[0] จะคืนค่าที่พบบ่อยที่สุด (ส่วน [0] รองรับกรณีที่มีหลายฐานนิยม)
import pandas as pd
import numpy as np
df = pd.DataFrame({
'status': ['active', 'inactive', None, 'active', None, 'active']
})
most_common = df['status'].mode()[0]
print('Mode:', most_common) # active
df['status'] = df['status'].fillna(most_common)
print(df['status'].tolist())
# ['active', 'inactive', 'active', 'active', 'active', 'active']การเติมค่าไปข้างหน้าด้วย ffill()
การเติมค่าไปข้างหน้า (หรือเรียกว่า last-observation-carried-forward, LOCF) จะส่งต่อค่าล่าสุดที่ใช้ได้ (ไม่ใช่ NaN) ไปข้างหน้าเพื่อเติมตำแหน่ง NaN ถัดไป วิธีนี้เหมาะอย่างยิ่งกับข้อมูล อนุกรมเวลา ที่ค่าการวัดยังคงเดิมจนกว่าจะมีการอัปเดต เช่น สถานะอุปกรณ์ ระดับราคา หรือค่าที่อ่านได้จากเซนเซอร์ซึ่งเปลี่ยนเฉพาะเมื่อเกิดเหตุการณ์บางอย่าง
import pandas as pd
import numpy as np
price = pd.Series(
[100, np.nan, np.nan, 105, np.nan, 110],
index=pd.date_range('2024-01', periods=6, freq='ME')
)
filled = price.ffill()
print(filled)
# 2024-01-31 100.0
# 2024-02-29 100.0
# 2024-03-31 100.0
# 2024-04-30 105.0
# 2024-05-31 105.0
# 2024-06-30 110.0การเติมค่าย้อนกลับด้วย bfill()
การเติมค่าย้อนกลับ (next-observation-carried-backward, NOCB) จะส่งต่อค่าถัดไปที่ใช้ได้ย้อนกลับมาเติมตำแหน่ง NaN ก่อนหน้า วิธีนี้มีประโยชน์เมื่อคุณทราบว่าข้อมูลในอนาคตสามารถเติมค่าที่หายไปในอดีตได้ เช่น เมื่อได้รับข้อมูลสิ้นเดือนและต้องเติมค่าย้อนกลับให้กับวันต่าง ๆ ในเดือนนั้นก่อนที่จะได้รับรายงาน
import pandas as pd
import numpy as np
df = pd.DataFrame({'value': [np.nan, np.nan, 3, np.nan, 5]})
print(df['value'].bfill())
# 0 3.0
# 1 3.0
# 2 3.0
# 3 5.0
# 4 5.0
# dtype: float64พารามิเตอร์ limit สำหรับการเติมค่าไปข้างหน้าและย้อนกลับ
ทั้ง ffill() และ bfill() รองรับพารามิเตอร์ limit ซึ่งใช้จำกัดจำนวนค่า NaN ที่อยู่ติดกันและจะถูกเติม วิธีนี้สำคัญเมื่อคุณต้องการส่งต่อค่าไปข้างหน้าเพียงช่วงว่างสั้น ๆ เท่านั้น ส่วนช่วงว่างยาวควรคงเป็น NaN เพื่อสื่อว่าข้อมูลหายไปจริง ไม่ใช่เพียงมาถึงล่าช้า
import pandas as pd
import numpy as np
s = pd.Series([1.0, np.nan, np.nan, np.nan, 5.0])
# Fill only the first NaN gap, leave the rest
print(s.ffill(limit=1))
# 0 1.0
# 1 1.0 <- filled
# 2 NaN <- still NaN (limit reached)
# 3 NaN
# 4 5.0การเติมค่าในแต่ละคอลัมน์ด้วยวิธีที่แตกต่างกัน
ใน DataFrame จริง คอลัมน์แต่ละคอลัมน์อาจต้องใช้กลยุทธ์การเติมค่าที่แตกต่างกัน ให้ส่ง พจนานุกรมเข้าไปใน fillna() โดยคีย์คือชื่อคอลัมน์และค่าคือค่าที่จะใช้เติม วิธีนี้ใช้การแทนค่าเฉพาะคอลัมน์ได้ภายในการเรียกครั้งเดียว ซึ่งเป็นระเบียบกว่าการเรียก fillna แยกหลายครั้งต่อเนื่องกัน
import pandas as pd
import numpy as np
df = pd.DataFrame({
'age': [25, np.nan, 30],
'income': [50000, np.nan, 70000],
'country': ['USA', np.nan, 'UK']
})
fill_values = {
'age': df['age'].median(),
'income': df['income'].mean(),
'country': 'Unknown'
}
filled = df.fillna(fill_values)
print(filled)
# age income country
# 0 25.0 50000.0 USA
# 1 27.5 60000.0 Unknown
# 2 30.0 70000.0 UKการแทนค่าที่คำนึงถึงกลุ่ม
กลยุทธ์ที่ซับซ้อนขึ้นคือการเติมค่า NaN ด้วย ค่าเฉลี่ยหรือค่ามัธยฐานของกลุ่ม แทนค่าเฉลี่ยของคอลัมน์ทั้งหมด ตัวอย่างเช่น เติมเงินเดือนที่หายไปด้วยค่ามัธยฐานของเงินเดือนในหมวดหมู่งานนั้น วิธีนี้รักษาโครงสร้างของกลุ่มย่อยไว้ และให้ค่าที่แทนได้สมจริงกว่าการใช้สถิติรวมทั้งคอลัมน์
import pandas as pd
import numpy as np
df = pd.DataFrame({
'dept': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
'salary': [90000, np.nan, 50000, np.nan, 110000]
})
# Fill salary NaN with the median salary for each department
df['salary'] = df.groupby('dept')['salary'].transform(
lambda x: x.fillna(x.median())
)
print(df)
# dept salary
# 0 Eng 90000.0
# 1 Eng 100000.0 <- group median (90k+110k)/2
# 2 HR 50000.0
# 3 HR 50000.0
# 4 Eng 110000.0การเติมค่าคงที่สำหรับระบุค่าพิเศษ
บางครั้งค่าที่เหมาะสมสำหรับการแทนค่าคือ ค่าพิเศษสำหรับระบุสถานะ ซึ่งสื่อว่า “ไม่ทราบค่า” แทนที่จะเป็นค่าการวัดจริง เช่น -1 สำหรับอายุที่ไม่ทราบค่า, 'N/A' สำหรับหมวดหมู่ที่ไม่ทราบค่า หรือ False สำหรับแฟล็กบูลีนที่ไม่ทราบค่า ค่าพิเศษเหล่านี้เหมาะสมเมื่อโค้ดส่วนถัดไปตรวจสอบค่าเหล่านี้โดยเฉพาะ และจัดการต่างจากข้อมูลจริง
import pandas as pd
import numpy as np
df = pd.DataFrame({
'user_id': [1, 2, 3],
'referral_source': ['email', np.nan, 'ad'],
'trial_days': [14, np.nan, 7]
})
df['referral_source'] = df['referral_source'].fillna('unknown')
df['trial_days'] = df['trial_days'].fillna(-1).astype(int)
print(df)
# user_id referral_source trial_days
# 0 1 email 14
# 1 2 unknown -1
# 2 3 ad 7การเรียก fillna() ต่อเนื่องในกระบวนการประมวลผล
เช่นเดียวกับเมธอดทั้งหมดของ Pandas fillna() จะคืนค่า DataFrame ใหม่ และนำไปใช้ต่อใน สายโซ่เมธอดได้อย่างราบรื่น การเรียก .fillna() หลัง .dropna() จะใช้กลยุทธ์สองขั้นตอน ได้แก่ ลบแถวที่ไม่มีคอลัมน์สำคัญ แล้วเติมค่า NaN ที่เหลือในคอลัมน์ทางเลือกด้วยค่าเริ่มต้นที่สมเหตุสมผล ทั้งหมดนี้อยู่ในกระบวนการประมวลผลเดียวที่อ่านเข้าใจง่าย
import pandas as pd
import numpy as np
df = pd.DataFrame({
'user_id': [1, None, 3, 4],
'score': [88, 95, np.nan, 76],
'label': ['A', 'B', None, 'D']
})
cleaned = (
df
.dropna(subset=['user_id'])
.fillna({'score': df['score'].mean(), 'label': 'Unknown'})
)
print(cleaned)
# user_id score label
# 0 1.0 88.0 A
# 2 3.0 86.3 Unknown
# 3 4.0 76.0 Dการตรวจสอบว่าไม่มี NaN เหลืออยู่
หลังการแทนค่า ควร ตรวจสอบ เสมอว่าไม่มีค่า NaN เหลืออยู่ในคอลัมน์ที่คุณจัดการ เรียกใช้ df.isna().sum() หรือยืนยันว่าจำนวนค่าเป็นศูนย์ หากจำนวนที่ไม่ใช่ศูนย์เกิดขึ้นโดยไม่คาดคิด แสดงว่า fillna ของคุณอาจตกหล่นบางกรณี เช่น คอลัมน์มีชนิดข้อมูลที่ทำให้เติมค่าไม่ได้ หรือคุณลืมใส่คอลัมน์หนึ่งไว้ในพจนานุกรม
import pandas as pd
import numpy as np
df = pd.DataFrame({'a': [1.0, np.nan, 3.0], 'b': [np.nan, 2.0, 3.0]})
filled = df.fillna(0)
# Verify
assert filled.isna().sum().sum() == 0, 'Some NaN remain!'
print('All NaN filled successfully')
print(filled.isna().sum())
# a 0
# b 0
# dtype: int64ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับการเติมค่าที่หายไปใน Pandas
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า fillna(scalar) จะแทนที่ NaN ทั้งหมดด้วยค่าคงที่, fillna(mean/median) จะแทนค่าด้วยสถิติของคอลัมน์ และ ffill()/bfill() จะส่งต่อค่าที่อยู่ติดกันสำหรับข้อมูลอนุกรมเวลา ส่ง พจนานุกรมให้ fillna() เพื่อใช้กลยุทธ์เฉพาะคอลัมน์ และใช้ groupby().transform() สำหรับการแทนค่าที่คำนึงถึงกลุ่ม บทถัดไป เราจะพูดถึงการประมาณค่าแทรกและเวลาที่ควรเลือกใช้เทคนิคการแทนค่าขั้นสูง
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การเติมค่าที่หายไป” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเติมค่าที่หายไป” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Pandas & NumPy Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Pandas & NumPy Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเติมค่าที่หายไป”
แทนที่ NaN ด้วยค่าคงที่ ค่าเฉลี่ยของคอลัมน์ การเติมค่าจากด้านหน้า หรือการเติมค่าจากด้านหลัง โดยใช้ fillna() และพารามิเตอร์ method คุณปฏิบัติ Pandas & NumPy Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Pandas & NumPy Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Pandas & NumPy Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การเติมค่าที่หายไป” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Pandas & NumPy Academy นี้ได้ไหม
ได้ บทเรียน Pandas & NumPy Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การตรวจหาค่าที่หายไป
- การลบค่าที่หายไป
- การเติมค่าที่หายไป
- การประมาณค่าและการแทนค่าขั้นสูง