پاک‌سازی داده در Pandas یعنی تبدیل دادهٔ خام به جدولی که معنا، نوع و محدودیت‌هایش روشن باشد. این کار با اجرای خودکار dropna یا حذف همهٔ مقدارهای تکراری تمام نمی‌شود. هر تغییر باید به یک قاعدهٔ قابل‌توضیح متصل باشد؛ زیرا حذف یا جایگزینی نادرست می‌تواند پاسخ تحلیل را عوض کند، حتی اگر پس از آن هیچ خطای برنامه‌نویسی رخ ندهد.

در این راهنما، یک فایل سفارش را بررسی می‌کنیم که شناسه، تاریخ، شهر، تعداد و قیمت دارد. بعضی خانه‌ها خالی‌اند، شکل نوشتن شهرها یکسان نیست و چند ردیف دوباره ثبت شده‌اند. هدف این است که دادهٔ اصلی محفوظ بماند، تغییرها قابل‌پیگیری باشند و در پایان بتوانیم توضیح دهیم چه تعداد ردیف پذیرفته یا رد شده است. این روش برای تحلیل و آماده‌سازی دادهٔ یادگیری ماشین کاربرد دارد.

پیش از read_csv قرارداد داده را بنویسید

برای هر ستون، معنا و نوع موردانتظار را مشخص کنید. شناسهٔ سفارش ممکن است از رقم تشکیل شده باشد، اما عدد محاسباتی نیست؛ تبدیلش به عدد می‌تواند صفر ابتدایی را حذف کند. تاریخ نیز باید تقویم و منطقهٔ زمانی مشخص داشته باشد. اگر واحد قیمت معلوم نباشد، هیچ تابعی نمی‌تواند تشخیص دهد یک مقدار به ریال ثبت شده یا تومان.

پیش از پاک‌سازی، یک کپی تغییرناپذیر از فایل ورودی نگه دارید. زمان دریافت و منبع غیرمحرمانهٔ فایل را ثبت کنید. نمونهٔ کوچک را برای شناخت جداکننده، کدگذاری و نام ستون‌ها بررسی کنید. اگر داده از چند سامانه آمده، فرض نکنید ستون هم‌نام در همهٔ آن‌ها تعریف یکسان دارد. اختلاف معنایی معمولاً خطرناک‌تر از تفاوت سادهٔ قالب است و با تبدیل نوع حل نمی‌شود.

DataFrame و Series را کاربردی بشناسید

DataFrame ساختاری جدولی با ستون‌های نام‌دار و index است. Series معمولاً یک ستون یا دنبالهٔ یک‌بعدی با برچسب را نمایش می‌دهد. index الزاماً شناسهٔ تجاری نیست؛ پس از فیلترکردن ممکن است پیوسته نباشد و این طبیعی است. اگر لازم است سفارش‌ها یکتا باشند، آن ویژگی را با ستون شناسه بررسی کنید، نه با ظاهر شمارهٔ ردیف‌ها.

برای بررسی اولیه از head، info و شمارش مقدارهای خالی استفاده کنید. head فقط ابتدای داده را نشان می‌دهد و شاهد سلامت کل فایل نیست. چند نمونهٔ تصادفی، سطرهای انتهایی و خلاصهٔ دامنهٔ ستون‌ها را نیز ببینید. اگر میلیون‌ها ردیف دارید، روش بررسی باید متناسب با اندازه باشد؛ ولی حتی در فایل کوچک هم کیفیت را از روی پنج ردیف اول قضاوت نکنید.

خواندن کنترل‌شده و تبدیل نوع

هنگام خواندن، dtype شناسه‌ها و قرارداد مقدارهای خالی را تا حد لازم مشخص کنید. بعضی عبارت‌ها ممکن است واقعاً نام یا کد باشند، نه نشانهٔ تهی‌بودن. سپس ستون‌های عددی را با to_numeric تبدیل کنید و موارد ناموفق را جدا بشمارید. گزینهٔ errors="coerce" خطا را به مقدار خالی تبدیل می‌کند؛ این کار مسئله را حل نکرده، فقط آن را در قالبی قابل‌بررسی نشان داده است.

import pandas as pd
raw = pd.DataFrame({
    "order_id": ["001", "002", "002", "003"],
    "quantity": ["2", "1", "1", "wrong"],
    "unit_price": ["100", "250", "250", "80"],
})
clean = raw.copy()
clean["quantity"] = pd.to_numeric(clean["quantity"], errors="coerce")
clean["unit_price"] = pd.to_numeric(clean["unit_price"], errors="coerce")
invalid = clean["quantity"].isna() | clean["unit_price"].isna()
rejected = clean.loc[invalid].copy()
accepted = clean.loc[~invalid].copy()

پس از تبدیل نوع، محدودیت دامنه را بررسی کنید. تعداد منفی ممکن است خطای ثبت باشد یا معنای مرجوعی داشته باشد؛ پاسخ از قرارداد داده می‌آید. ستون تاریخ نیز با to_datetime قابل‌تبدیل است، اما تاریخ شمسی را بدون تبدیل تقویم به‌عنوان میلادی تفسیر نکنید. اگر روز و ماه مبهم‌اند، قالب را صریح تعیین کنید و تعداد تاریخ‌های ناموفق را در گزارش بیاورید.

دادهٔ گمشده؛ حذف، جایگزینی یا حفظ؟

برای تصمیم دربارهٔ مقدار خالی، ابتدا علت را بشناسید. آیا داده ثبت نشده، اندازه‌گیری ممکن نبوده یا آن ویژگی برای نمونه موضوعیت ندارد؟ یک مقدار تهی می‌تواند معنای متفاوتی در ستون درآمد و تاریخ لغو سفارش داشته باشد. حذف همهٔ سطرهای دارای هر خانهٔ خالی، ممکن است بخش بزرگی از گروه خاصی از مشتریان را کنار بگذارد و تحلیل را سوگیرانه کند.

جایگزینی با میانگین، میانه یا مقدار ثابت نیز تصمیم خنثی نیست. میانه برای بعضی داده‌های عددی با مقدار پرت مقاوم‌تر است، اما ساختار رابطه‌ها را تغییر می‌دهد. در یادگیری ماشین، پارامتر جایگزینی فقط روی آموزش برازش می‌شود. اگر از میانگین کل فایل شامل آزمون استفاده کنید، نشت داده رخ می‌دهد. برای گزارش توصیفی هم بهتر است تعداد جایگزینی‌ها و اثر آن بر نتیجه را نشان دهید.

استانداردسازی متن فارسی بدون تخریب معنا

در دادهٔ فارسی ممکن است ی و ک عربی، فاصلهٔ اضافی، نیم‌فاصله و رقم‌های فارسی و لاتین کنار هم دیده شوند. برای نام شهر یا دسته، می‌توان نگاشت محدود و مستندی ساخت. اما یکسان‌سازی شدید تمام متن‌ها ممکن است بخشی از معنا یا تمایز واقعی را حذف کند. نام اشخاص، کد محصول و متن آزاد را با یک قانون عمومی و بدون آزمون تغییر ندهید.

برای ستون دسته‌ای، ابتدا فهرست مقدارهای یکتا و فراوانی را ببینید. نگاشت «تهران » به «تهران» قابل‌توضیح است؛ اما یکی‌کردن دو نام نزدیک شاید نیازمند دانش دامنه باشد. مقدار خام را در نسخهٔ اصلی حفظ و نتیجهٔ استانداردشده را در ستون یا خروجی جدا نگه دارید. این کار امکان بررسی شکایت، رفع اشتباه نگاشت و بازتولید گزارش را فراهم می‌کند.

ردیف تکراری با سفارش تکراری یکسان نیست

duplicated می‌تواند بر اساس همهٔ ستون‌ها یا زیرمجموعه‌ای از آن‌ها تکرار را تشخیص دهد. اما اینکه کدام ستون‌ها کلید هستند، تصمیمی تجاری است. یک سفارش ممکن است چند قلم کالا داشته باشد و شناسهٔ سفارش به‌تنهایی یکتا نباشد. حذف تکرار بر اساس آن شناسه، خرید واقعی را از بین می‌برد. ابتدا سطح هر ردیف را تعریف کنید: سفارش، قلم سفارش یا رویداد؟

در مثال کوچک، دو ردیف یکسان برای سفارش دوم داریم و می‌توانیم با یک فرض صریح آن‌ها را حذف کنیم. در دادهٔ واقعی، زمان ثبت یا شناسهٔ رویداد ممکن است لازم باشد. پس از حذف، تعداد و مبلغ قبل و بعد را مقایسه کنید. اگر تغییر بزرگ است، قبل از ادامه علت را پیدا کنید. یک عملیات درست کتابخانه‌ای می‌تواند بر اساس کلید اشتباه، نتیجهٔ کاملاً نادرستی بسازد.

before = len(accepted)
accepted = accepted.drop_duplicates(subset=["order_id", "quantity", "unit_price"])
removed_duplicates = before - len(accepted)
accepted["amount"] = accepted["quantity"] * accepted["unit_price"]
assert len(rejected) == 1
assert removed_duplicates == 1
assert accepted["amount"].sum() == 450

مقدار پرت را خودکار حذف نکنید

مقدار پرت ممکن است خطای ورود داده باشد، اما می‌تواند رویدادی واقعی و مهم هم باشد. سفارش بسیار بزرگ، مصرف غیرعادی یا مشتری خاص لزوماً دادهٔ خراب نیست. روش‌هایی مثل بازهٔ میان‌چارکی برای علامت‌گذاری مفیدند، نه صدور حکم قطعی. پیش از حذف، واحد، دامنهٔ مجاز و سابقهٔ ثبت را بررسی کنید و در صورت امکان با منبع داده تطبیق دهید.

اگر حذف یا محدودسازی انتخاب شد، آستانه و دلیل را ثبت کنید و نتیجه را با حالت بدون این تغییر مقایسه کنید. در مدل‌سازی، آستانهٔ مبتنی بر توزیع باید فقط از آموزش به دست بیاید. همچنین برای هر گروه ممکن است دامنهٔ طبیعی متفاوت باشد؛ یک قانون سراسری می‌تواند نمونه‌های درست یک گروه کوچک را حذف کند. کیفیت داده نیازمند قضاوت دامنه‌ای است، نه فقط تشخیص فاصله از میانگین.

اتصال جدول‌ها؛ نقطهٔ پرخطر تحلیل

وقتی جدول سفارش را به جدول مشتری وصل می‌کنید، انتظار رابطه را مشخص کنید. اگر هر مشتری یک ردیف دارد، اتصال باید چندبه‌یک باشد. وجود مشتری تکراری در جدول دوم می‌تواند تعداد سطر و درآمد را چند برابر کند. گزینهٔ validate در merge کمک می‌کند این انتظار به آزمون اجراشدنی تبدیل شود. از موفقیت اجرای merge نتیجه نگیرید که اتصال از نظر تحلیلی درست است.

پیش و پس از اتصال، تعداد سطر، تعداد شناسهٔ یکتا و جمع مبلغ را کنترل کنید. بررسی indicator نیز نشان می‌دهد کدام کلیدها فقط در یکی از جدول‌ها بوده‌اند. تصمیم دربارهٔ INNER یا LEFT باید از سؤال تحلیل بیاید؛ حذف مشتریِ فاقد مشخصات ممکن است گزارش فروش را ناقص کند. همین منطق در SQL نیز تکرار می‌شود و یادگیری آن به هر دو ابزار کمک می‌کند.

loc، انتساب روشن و تبدیل قابل‌بازتولید

برای انتخاب سطر و ستون با برچسب، loc انتخاب مناسبی است و iloc با موقعیت کار می‌کند. انتخاب را با هدف روشن بنویسید و از انتساب زنجیره‌ای مبهم دوری کنید. یک عبارت مانند انتخاب زیرجدول و سپس تغییر ستونی از آن، بسته به نسخه و رفتار کپی می‌تواند گیج‌کننده باشد. تبدیل روی DataFrame مشخص و انتساب با loc، خوانایی و پیش‌بینی‌پذیری بیشتری دارد.

فرایند پاک‌سازی را در یک برنامهٔ قابل‌اجرای دوباره نگه دارید، نه فقط مجموعه‌ای از کلیک‌ها یا سلول‌های با ترتیب نامعلوم. اگر از دفترچه استفاده می‌کنید، اجرای کامل از ابتدا باید همان خروجی را بسازد. نسخهٔ کتابخانه و قرارداد ورودی را ثبت کنید. هدف این نیست که برای یک فایل کوچک معماری سنگین بسازید؛ هدف آن است که هفتهٔ بعد علت یک عدد در گزارش قابل‌یافتن باشد.

گزارش کیفیت و آزمون خروجی

گزارش کیفیت حداقل باید تعداد ورودی، مقدارهای خالی مهم، تبدیل‌های ناموفق، تکرار حذف‌شده و تعداد نهایی را داشته باشد. برای هر قانون، یک مثال کوچک بنویسید که انتظار درست را نشان دهد. رابطهٔ تعدادها باید توضیح‌پذیر باشد؛ مثلاً ورودی برابر با پذیرفته‌شده، ردشده و تکرارهای حذف‌شده شود، اگر این دسته‌ها واقعاً جدا و بدون هم‌پوشانی تعریف شده‌اند.

علاوه بر تعداد، چند شرط معنایی را بررسی کنید: شناسه‌ها حفظ شده‌اند، مبلغ از تعداد و قیمت محاسبه شده و کلید موردانتظار یکتاست. خروجی را همراه دادهٔ محرمانه در مخزن عمومی نگذارید. برای آزمون، نمونهٔ ساختگی و کوچک کافی است. این جداسازی باعث می‌شود همکار بتواند منطق را بررسی کند، بدون اینکه به اطلاعات واقعی مشتریان دسترسی داشته باشد.

نمونهٔ گزارش پاک‌سازی که قابل‌بازبینی باشد

فرض کنید هزار ردیف وارد شده، ده ردیف به دلیل نوع نامعتبر کنار گذاشته و پنج ردیف تکراریِ تأییدشده حذف شده است. اگر این گروه‌ها جدا باشند، انتظار داریم نهصد و هشتاد و پنج ردیف باقی بماند. اما اگر یک ردیف هم نامعتبر و هم تکراری باشد، جمع سادهٔ حذف‌ها درست نیست. ترتیب قوانین و هم‌پوشانی آن‌ها باید در گزارش روشن باشد تا تعدادها صرفاً ظاهراً مرتب نباشند.

برای هر مرحله، نام قانون، تعداد متاثر و نتیجهٔ کنترل را ذخیره کنید. لازم نیست همهٔ محتوای ردیف را در گزارش عمومی بیاورید؛ شناسهٔ غیرحساس یا شمارهٔ ردیف می‌تواند برای بازبینی داخلی کافی باشد. اگر شناسه خودش حساس است، دسترسی و شکل گزارش را متناسب کنید. هدف ردیابی تصمیم است، نه تکثیر دادهٔ شخصی در چند فایل. گزارش کیفیت نیز باید همان سیاست نگهداری دادهٔ اصلی را رعایت کند.

یک آزمون مهم، اجرای دوبارهٔ فرایند روی همان ورودی و مقایسهٔ خروجی است. اگر هر بار ردیف متفاوتی باقی می‌ماند، ترتیب یا قاعدهٔ انتخاب مبهم است. در حذف تکرار، تعیین اینکه اولین یا آخرین ثبت معتبر است باید از زمان و معنا بیاید، نه ترتیب اتفاقی فایل. برای دادهٔ چندمنبعی، اولویت منبع را هم صریح تعریف کنید تا تغییر ترتیب دریافت، نتیجه را عوض نکند.

پس از تکمیل، یک نفر دیگر باید بتواند با دیدن قرارداد و گزارش بفهمد چرا جمع فروش تغییر کرده است. اگر پاسخ تنها «Pandas این‌طور حساب کرد» باشد، بازبینی کافی نیست. کتابخانه عملیات را اجرا می‌کند؛ مسئولیت معنا، انتخاب قانون و توضیح اثر آن همچنان با تحلیلگر است. این تفکیک، پاک‌سازی را از چند دستور پراکنده به فرایندی قابل‌اعتماد تبدیل می‌کند.

تمرین و پرسش‌های متداول

یک فایل ده‌ردیفی بسازید که یک شناسهٔ با صفر ابتدایی، یک تاریخ نامعتبر، یک مقدار خالی و یک تکرار واقعی داشته باشد. پیش از نوشتن کد، برای هر مشکل تصمیم بگیرید. سپس پاک‌سازی را اجرا و دو گزارش قبل و بعد تولید کنید. اگر نمی‌توانید دلیل تغییر هر ردیف را توضیح دهید، فرایند هنوز آمادهٔ استفادهٔ جدی نیست؛ حتی اگر فایل نهایی ظاهری تمیز داشته باشد.

آیا dropna بهترین روش پاک‌سازی است؟

خیر. این تابع فقط عملیاتی برای حذف براساس مقدارهای خالی است و درستی تصمیم شما را نمی‌سنجد. ممکن است برای ستون ضروری مناسب باشد و برای ستون اختیاری باعث اتلاف داده شود. ابتدا اهمیت ستون، الگوی گمشدگی و اثر حذف بر گروه‌ها را بررسی کنید. سپس قانون محدود و قابل‌آزمونی بنویسید و تعداد حذف‌ها را گزارش دهید.

چرا نتیجهٔ جمع پس از merge تغییر می‌کند؟

احتمال اتصال چندبه‌چند یا وجود کلید تکراری را بررسی کنید. یک ردیف سفارش ممکن است چند بار با جدول دوم تطبیق یافته باشد. تعداد سطر و فراوانی کلیدها را پیش از اتصال کنترل کنید و validate مناسب بگذارید. پاک‌سازی بعد از اتصال همیشه راه‌حل نیست؛ حذف تکرار خروجی ممکن است دادهٔ واقعی را نیز کنار بگذارد.

آیا همین جدول برای مدل‌سازی آماده است؟

نه لزوماً. آماده‌بودن برای گزارش با آماده‌بودن برای مدل یکسان نیست. باید زمان دسترس‌پذیری ویژگی، جداسازی آموزش و آزمون، هدف و نشت داده را هم بررسی کنید. برای ادامه، مقالهٔ یادگیری ماشین و راهنمای ارزیابی مدل نشان می‌دهند چگونه همین جدول تمیز را بدون آلوده‌کردن آزمون به یک فرایند قابل‌اعتماد وصل کنید.

منابع و مطالعهٔ بیشتر

برای بررسی جزئیات و ادامهٔ مطالعه؛ متن این راهنما مستقلاً برای نوونتیکس نوشته شده است.