FA-TOOLS — Header Component

کدهای آماده pandas برای پاکسازی داده

رفیق برنامه‌نویس، تو دنیای دیتا، پاکسازی داده‌ها (Data Cleaning) حکم شست‌وشوی لباس چرک رو داره؛ کار سختیه ولی اگه درست انجام نشه، تمام زحمات بعدی‌ت به باد میره! داده‌های خام پر از حفره، خطا و ناهماهنگی‌ان که اگه پاکسازی نشن، مدل‌های یادگیری ماشین‌ت اشتباه می‌کنن و تحلیل‌هات به خطا میرن. تو این مقاله، قراره با هم چند تا کد کاربردیی و آماده از پایتون و کتابخونه قدرتمند pandas رو مرور کنیم که کار پاکسازی داده‌هات رو حسابی راحت می‌کنه. پس اگه دنبال ابزارهای خفن و آماده برای پروژه‌های دیتا ساینس و تحلیل داده‌هات هستی، یه سر به بخش کدهای آماده و اسنیپت‌های ما بزن تا کلی ابزار جذاب دیگه رو پیدا کنی! برای مشاوره یا اگه سوالی داشتی، می‌تونی با ما تماس بگیری: تماس: 09202232789

💡 نقشه راه پاکسازی داده با Pandas در یک نگاه! 💡

کدهای آماده pandas برای پاکسازی داده — تصویر 1

1. غیبت‌ها رو پیدا کن (Missing Values)

NaN، None و فضاهای خالی رو شناسایی و مدیریت کن. پر کردن، حذف کردن یا جایگزینی.

2. نوع داده رو درست کن (Data Types)

تبدیل ستون‌ها به نوع صحیح (عددی، تاریخ، متنی) برای جلوگیری از خطاها.

3. تکراری‌ها رو حذف کن (Duplicates)

ردیف‌های تکراری که ممکنه نتیجه ورودی اشتباه باشن رو حذف کن.

4. متن‌ها رو تمیز کن (Text Cleaning)

حذف فضاهای اضافه، تبدیل حروف، جایگزینی کاراکترهای خاص.

5. پرت‌ها رو کنترل کن (Outliers)

شناسایی و تصمیم‌گیری درباره مقادیر غیرعادی و دور از انتظار.

چرا پاکسازی داده اینقدر مهمه؟

کدهای آماده pandas برای پاکسازی داده — تصویر 2
وقتی با داده کار می‌کنی، باید بدونی که هیچ دیتایی از اول تمیز و آماده نیست. بیشتر اوقات، داده‌ها از منابع مختلفی میان که هر کدوم شیوه ذخیره‌سازی خودشون رو دارن. مثلاً ممکنه یه جای دیگه “سن” رو با عدد ذخیره کنن، یه جای دیگه با رشته (مثلاً “۲۰ سال”). اگه این ناهماهنگی‌ها رو رفع نکنی، نتایج تحلیل‌هات اشتباه از آب درمیاد، مدل‌هات عملکرد خوبی نخواهند داشت و در نهایت، تصمیماتی که بر اساس اون تحلیل‌ها می‌گیری، غلط خواهند بود. پاکسازی داده مثل گذاشتن فونداسیون محکم برای یه ساختمونه؛ اگه فونداسیون قوی نباشه، کل ساختمون میلرزه.

۱. مدیریت مقادیر گمشده (Missing Values)

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

شناسایی مقادیر گمشده

اولین قدم اینه که بفهمی اصلاً چقدر داده گمشده داری و کجاها هستن. این کد بهت یه دید کلی میده:

import pandas as pd
import numpy as np

# فرض می‌کنیم DataFrame شما df باشه
df = pd.DataFrame({
    'ستون_A': [1, 2, np.nan, 4, 5],
    'ستون_B': [np.nan, 'apple', 'banana', np.nan, 'orange'],
    'ستون_C': [True, False, True, np.nan, False]
})

# تعداد مقادیر گمشده در هر ستون
print("تعداد مقادیر گمشده در هر ستون:n", df.isnull().sum())

# درصد مقادیر گمشده در هر ستون
print("nدرصد مقادیر گمشده در هر ستون:n", df.isnull().sum() / len(df) * 100)

روش‌های جایگزینی (Imputation)

اگه تعداد داده‌های گمشده کم باشه، می‌تونی اون‌ها رو با یه مقدار منطقی پر کنی. انتخاب روش جایگزینی خیلی به نوع داده و هدفت بستگی داره:
  • پر کردن با مقدار ثابت: مثلاً صفر یا “نامشخص”.
  • پر کردن با میانگین (Mean): برای داده‌های عددی.
  • پر کردن با میانه (Median): وقتی داده‌ها شامل پرت‌ها هستن، میانه گزینه بهتریه.
  • پر کردن با مُد (Mode): برای داده‌های دسته‌بندی (Categorical).
  • Fill Forward (ffill) یا Fill Backward (bfill): پر کردن با مقدار قبلی یا بعدی، برای داده‌های سری زمانی مفید است.

# پر کردن با مقدار ثابت
df_filled_const = df.fillna(0) # یا مثلاً 'unknown' برای ستون‌های متنی
print("nبعد از پر کردن با 0:n", df_filled_const)

# پر کردن با میانگین (فقط برای ستون‌های عددی)
df['ستون_A'] = df['ستون_A'].fillna(df['ستون_A'].mean())
print("nستون A بعد از پر کردن با میانگین:n", df)

# پر کردن با مُد (مثلاً برای ستون B)
# برای ستون‌های متنی یا دسته‌بندی، مد بهترین انتخابه
df['ستون_B'] = df['ستون_B'].fillna(df['ستون_B'].mode()[0])
print("nستون B بعد از پر کردن با مد:n", df)

# پر کردن با مقدار قبلی (forward fill)
df_ffill = df.fillna(method='ffill')
print("nبعد از ffill:n", df_ffill)

حذف ردیف‌ها یا ستون‌ها با مقادیر گمشده

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

# حذف تمام ردیف‌هایی که حداقل یک مقدار گمشده دارند
df_dropped_rows = df.dropna()
print("nبعد از حذف ردیف‌های دارای NaN:n", df_dropped_rows)

# حذف ستون‌هایی که حداقل یک مقدار گمشده دارند
df_dropped_cols = df.dropna(axis=1)
print("nبعد از حذف ستون‌های دارای NaN:n", df_dropped_cols)

# حذف ردیف‌هایی که تمام مقادیرشان NaN است
df_dropped_all_na = df.dropna(how='all')
print("nبعد از حذف ردیف‌هایی که تماماً NaN هستند:n", df_dropped_all_na)

۲. تصحیح نوع داده (Data Type Conversion)

گاهی اوقات Pandas نوع داده رو به اشتباه تشخیص میده. مثلاً اعداد رو به عنوان رشته (object) می‌شناسه، یا تاریخ‌ها رو به جای datetime، رشته حساب می‌کنه. این اشتباهات باعث میشه عملیات ریاضی یا کار با تاریخ‌ها ممکن نباشه.

df_types = pd.DataFrame({
    'عدد_رشته_ای': ['10', '20', '30', '40a'],
    'تاریخ_رشته_ای': ['2023-01-01', '2023-01-02', '2023-01-03', 'Invalid-Date'],
    'بولی_عددی': [1, 0, 1, 0]
})

print("انواع داده قبل از تغییر:n", df_types.dtypes)

# تبدیل ستون عددی رشته‌ای به عددی (با مدیریت خطا)
df_types['عدد_رشته_ای'] = pd.to_numeric(df_types['عدد_رشته_ای'], errors='coerce')
# 'coerce' باعث میشه مقادیری که قابل تبدیل نیستن به NaN تبدیل بشن

# تبدیل ستون تاریخ رشته‌ای به datetime (با مدیریت خطا)
df_types['تاریخ_رشته_ای'] = pd.to_datetime(df_types['تاریخ_رشته_ای'], errors='coerce')

# تبدیل ستون بولی_عددی به بولی
df_types['بولی_عددی'] = df_types['بولی_عددی'].astype(bool)

print("nانواع داده بعد از تغییر:n", df_types.dtypes)
print("nDataFrame بعد از تغییر انواع داده:n", df_types)

۳. حذف ردیف‌های تکراری (Duplicate Rows)

داده‌های تکراری می‌تونن نتایج تحلیل رو منحرف کنن و باعث سوگیری بشن. خوشبختانه، Pandas ابزارهای ساده‌ای برای شناسایی و حذف این ردیف‌ها داره.

df_dup = pd.DataFrame({
    'id': [1, 2, 2, 3, 4, 1],
    'نام': ['علی', 'رضا', 'رضا', 'مریم', 'حسن', 'علی'],
    'شهر': ['تهران', 'اصفهان', 'اصفهان', 'شیراز', 'تهران', 'تهران']
})

print("DataFrame اصلی با تکراری‌ها:n", df_dup)

# شناسایی ردیف‌های تکراری (اولین نمونه رو حفظ می‌کنه)
print("nردیف‌های تکراری (boolean mask):n", df_dup.duplicated())

# حذف ردیف‌های کاملاً تکراری
df_no_duplicates = df_dup.drop_duplicates()
print("nDataFrame بدون ردیف‌های کاملاً تکراری:n", df_no_duplicates)

# حذف تکراری‌ها بر اساس ستون‌های خاص (مثلاً 'id' و 'نام')
df_no_duplicates_subset = df_dup.drop_duplicates(subset=['id', 'نام'])
print("nDataFrame بدون تکراری‌های بر اساس 'id' و 'نام':n", df_no_duplicates_subset)

# نگه داشتن آخرین تکراری به جای اولین
df_keep_last = df_dup.drop_duplicates(keep='last')
print("nDataFrame بدون تکراری‌ها (نگه داشتن آخرین):n", df_keep_last)

۴. پاکسازی و استانداردسازی داده‌های متنی

داده‌های متنی معمولاً پر از دردسرن. از حروف بزرگ و کوچیک نامنظم گرفته تا فضاهای اضافه و کاراکترهای خاص. برای تحلیل درست، باید این داده‌ها رو استانداردسازی کنی.

df_text = pd.DataFrame({
    'محصول': ['  لپتاپ ', 'کـیـبورد', 'موس GAMING', 'مانیتور ', 'لپتاپ']
})

print("DataFrame اصلی متنی:n", df_text)

# حذف فضاهای اضافه از ابتدا و انتهای رشته
df_text['محصول_تمیز'] = df_text['محصول'].str.strip()

# تبدیل به حروف کوچک (یا بزرگ)
df_text['محصول_تمیز'] = df_text['محصول_تمیز'].str.lower()

# جایگزینی کاراکترهای خاص (مثلاً 'ـ' با ' ')
df_text['محصول_تمیز'] = df_text['محصول_تمیز'].str.replace('ـ', ' ')

# حذف کاراکترهای غیر الفبا-عددی
df_text['محصول_تمیز'] = df_text['محصول_تمیز'].str.replace('[^a-z0-9s]', '', regex=True)

# حذف فضاهای اضافی بین کلمات
df_text['محصول_تمیز'] = df_text['محصول_تمیز'].str.replace('s+', ' ', regex=True)


print("nDataFrame بعد از پاکسازی متن:n", df_text)

۵. مدیریت مقادیر پرت (Outliers)

مقادیر پرت (Outliers) داده‌هایی هستن که به شدت از بقیه داده‌ها فاصله دارن و ممکنه باعث اشتباه در تحلیل‌های آماری یا عملکرد ضعیف مدل‌های یادگیری ماشین بشن. روش‌های مختلفی برای شناسایی و مدیریت این مقادیر وجود داره. اینجا به یکی از رایج‌ترین روش‌ها، یعنی استفاده از IQR (Interquartile Range) اشاره می‌کنم.

df_outlier = pd.DataFrame({
    'درآمد': [1000, 1200, 1100, 1500, 900, 2000, 10000, 1100, 1300] # 10000 یک پرت است
})

# محاسبه Q1 (چارک اول) و Q3 (چارک سوم)
Q1 = df_outlier['درآمد'].quantile(0.25)
Q3 = df_outlier['درآمد'].quantile(0.75)
IQR = Q3 - Q1

# تعریف حد پایین و بالای تشخیص پرت
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR

print(f"Q1: {Q1}, Q3: {Q3}, IQR: {IQR}")
print(f"حد پایین: {lower_bound}, حد بالا: {upper_bound}")

# شناسایی پرت‌ها
outliers = df_outlier[(df_outlier['درآمد']  upper_bound)]
print("nمقادیر پرت شناسایی شده:n", outliers)

# روش‌های مدیریت پرت‌ها:
# 1. حذف پرت‌ها
df_no_outliers = df_outlier[~((df_outlier['درآمد']  upper_bound))]
print("nDataFrame بعد از حذف پرت‌ها:n", df_no_outliers)

# 2. محدود کردن (Capping) پرت‌ها به حد بالا یا پایین
df_capped = df_outlier.copy()
df_capped['درآمد'] = np.where(df_capped['درآمد'] > upper_bound, upper_bound, df_capped['درآمد'])
df_capped['درآمد'] = np.where(df_capped['درآمد'] < lower_bound, lower_bound, df_capped['درآمد'])
print("nDataFrame بعد از Capping پرت‌ها:n", df_capped)

جدول مقایسه روش‌های مدیریت مقادیر گمشده

روش شرح و کاربرد
حذف (dropna) حذف کامل ردیف یا ستون حاوی NaN. بهترین گزینه وقتی مقادیر گمشده کم و تصادفی هستند.
پر کردن با مقدار ثابت (fillna(0)) جایگزینی NaN با یک مقدار مشخص (مثلاً 0، ‘نامشخص’). ساده و سریع، اما ممکن است سوگیری ایجاد کند.
پر کردن با میانگین/میانه (fillna(mean/median)) جایگزینی NaN با میانگین یا میانه ستون. برای داده‌های عددی. میانه در حضور پرت‌ها بهتر عمل می‌کند.
پر کردن با مُد (fillna(mode)) جایگزینی NaN با پرتکرارترین مقدار ستون. بهترین گزینه برای داده‌های دسته‌بندی.
Fill Forward/Backward (ffill/bfill) پر کردن با مقدار قبلی (ffill) یا بعدی (bfill) در همان ستون. برای داده‌های سری زمانی یا ترتیبی مناسب است.

عیب‌یابی سریع (Troubleshooting) – مشکلاتی که ممکنه گیر بیفتی

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

۱. ارور ValueError: could not convert string to float

  • مشکل: داری سعی می‌کنی یه ستون رو به عددی تبدیل کنی، ولی توش مقادیر غیرعددی (مثلاً رشته‌های متنی یا کاراکترهای خاص) وجود داره.
  • راه‌حل: از pd.to_numeric() با آرگومان errors=’coerce’ استفاده کن. این کار باعث میشه مقادیر مشکل‌دار به NaN تبدیل بشن و بعداً می‌تونی اونا رو مدیریت کنی (حذف کنی یا پر کنی).
    
    df['ستون_عددی'] = pd.to_numeric(df['ستون_عددی'], errors='coerce')
        

۲. تاریخ‌ها درست تبدیل نمیشن یا فرمت‌های عجیب دارن

  • مشکل: ستون تاریخ‌ت فرمت‌های مختلفی داره (مثلاً “YYYY-MM-DD” و “MM/DD/YYYY”) یا شامل مقادیر نامعتبره.
  • راه‌حل: از pd.to_datetime() با errors=’coerce’ استفاده کن. اگه فرمت‌های زیادی داری، شاید لازم باشه قبلش با regex یا توابع apply() یه پیش‌پردازش روی رشته‌ها انجام بدی.
    
    df['ستون_تاریخ'] = pd.to_datetime(df['ستون_تاریخ'], errors='coerce')
        

۳. حذف ردیف‌های تکراری، اون چیزی که می‌خواستی رو حذف نمیکنه

  • مشکل: ممکنه تکراری‌ها فقط تو ستون‌های خاصی برات مهمن، نه کل ردیف.
  • راه‌حل: از آرگومان subset در drop_duplicates() استفاده کن تا فقط بر اساس ستون‌های مدنظرت تکراری‌ها رو حذف کنی. همچنین می‌تونی با keep=’last’ یا keep=False مشخص کنی کدوم نمونه رو نگه داره.
    
    df_cleaned = df.drop_duplicates(subset=['id', 'نام'], keep='first')
        

۴. عملکرد کند در پاکسازی داده‌های متنی بزرگ

  • مشکل: وقتی با میلیون‌ها ردیف متنی کار می‌کنی، استفاده از .str.replace() یا .apply() ممکنه خیلی طول بکشه.
  • راه‌حل: تا جایی که میشه از متدهای وکتورایز شده Pandas (یعنی همون متدهایی که با .str شروع میشن) استفاده کن. برای عملیات پیچیده‌تر، پکیج‌هایی مثل Dask یا modin می‌تونن کمک کنن تا کارها رو به صورت موازی انجام بدی و سرعت رو بالا ببری. همچنین استفاده از کامپایلرهای JIT (Just-In-Time) مثل Numba برای توابع apply() هم می‌تونه مفید باشه.
خب رفیق، این بود یه دید کلی و کدهای آماده Pandas برای پاکسازی داده‌هات. پاکسازی داده یه هنره که با تجربه بهتر میشی. هر چی بیشتر با داده‌های واقعی سروکله بزنی، بهتر می‌تونی مشکلات رو تشخیص بدی و راه‌حل مناسب براشون پیدا کنی. یادت باشه، کیفیت داده‌ها، کیفیت مدل‌ها و تحلیل‌های تو رو تعیین می‌کنه. پس وقت بذار و این بخش رو جدی بگیر! اگه دنبال کدهای آماده بیشتری تو زمینه‌های مختلف مثل CSS، HTML یا حتی وردپرس هستی، حتماً یه سری به سایت ما بزن. اطمینانی دارم که ابزارهای مورد نیازت رو اونجا پیدا می‌کنی!

Table of Contents

آخرین نوشته‌ها