در منظره دادههای مدرن، پایتون به عنوان زبان مشترک علم داده تثبیت شده است. در قلب این اکوسیستم دو کتابخانه قدرتمند NumPy و Pandas قرار دارند. اگرچه اغلب توسط مبتدیان به جای هم استفاده میشوند، اما اهداف متمایز اما مکملی دارند. NumPy عملیات آرایهای سطح پایین پایه را فراهم میکند، در حالی که Pandas بر پایه آن ساخته شده تا ساختارهای دادهای سطح بالا و شهودی برای دستکاری دادههای ساختاریافته ارائه دهد. این پست به بررسی عمیق نحوه استفاده مؤثر از این ابزارها برای توسعهدهندگان متوسط تا پیشرفته میپردازد.
درک معماری هسته
قبل از نوشتن حتی یک خط کد تحلیلی، درک آنچه در زیر سطح اتفاق میافتد حیاتی است. NumPy (پایتون عددی) عمدتاً بر انجام محاسبات سریع و کارآمد روی آرایهها و ماتریسهای بزرگ و چندبعدی متمرکز است. این کتابخانه شیء ndarray را معرفی میکند که اقلام همنوع را در یک بلوک پیوسته از حافظه ذخیره میکند و عملیات برداری را امکانپذیر میسازد که به طور قابل توجهی سریعتر از حلقههای استاندارد پایتون هستند.
Pandas، در مقابل، برای دستکاری و آمادهسازی دادهها طراحی شده است. این کتابخانه دو ساختار دادهای اصلی را معرفی میکند: Series (یک بعدی) و DataFrame (دو بعدی). یک DataFrame اساساً ساختاری شبیه به صفحه گسترده است که در آن ستونها میتوانند حاوی انواع دادهای متفاوت باشند. Pandas بر روی NumPy ساخته شده است، به این معنی که در زیر سطح، بسیاری از عملیات Pandas صرفاً فراخوانیهای بهینهشده NumPy هستند. درک این رابطه به توسعهدهندگان اجازه میدهد تا کدهای با عملکرد بهتر بنویسند با دانستن اینکه چه زمانی از سرعت خام NumPy و چه زمانی از راحتی Pandas استفاده کنند.
تکنیکهای ضروری دستکاری داده
برای توسعهدهندگان متوسط، ارزش نهفته نه تنها در بارگذاری داده، بلکه در تبدیل کارآمد آن است. وظایف رایج شامل فیلتر کردن، گروهبندی و مدیریت دادههای گمشده است. بیایید به یک مثال عملی شامل یک مجموعه داده فروش شبیهسازی شده نگاه کنیم.
اول، ما یک مجموعه داده را با استفاده از NumPy برای شدت محاسبات عددی تولید کرده و سپس آن را با Pandas ساختاردهی میکنیم:
import pandas as pd
import numpy as np
# شبیهسازی یک مجموعه داده با ارقام فروش تصادفی
np.random.seed(42)
data = {
'product': ['A', 'B', 'C', 'A', 'B', 'C'],
'region': ['North', 'South', 'North', 'South', 'North', 'South'],
'sales': np.random.randint(100, 1000, size=6),
'date': pd.date_range('2023-01-01', periods=6, freq='D')
}
df = pd.DataFrame(data)
print("Original DataFrame:")
print(df)
پس از بارگذاری داده، فیلتر کردن ساده میشود. برای یافتن تمام فروشهایی در منطقه 'شمال' که از 500 واحد بیشتر هستند، میتوانیم از نمایهگذاری بولی استفاده کنیم:
# فیلتر کردن دادهها
filtered_df = df[(df['region'] == 'North') & (df['sales'] > 500)]
print("\nFiltered Data:")
print(filtered_df)
عملیات گروهبندی جایی است که Pandas واقعاً میدرخشد. فرض کنید میخواهیم میانگین فروش را به ازای هر محصول محاسبه کنیم. با استفاده از روش groupby، میتوانیم این کار را در یک خط انجام دهیم:
# تجمیع
summary = df.groupby('product')['sales'].mean()
print("\nAverage Sales per Product:")
print(summary)
بهینهسازی عملکرد با برداریسازی
یک دام رایج برای توسعهدهندگانی که از پایتون استاندارد به سمت این ابزارها میآیند، استفاده از حلقههای صریح برای تبدیل داده است. این روش کند و غیرپایتونی است. در عوض، همیشه از عملیات برداری ارائه شده توسط هر دو کتابخانه NumPy و Pandas استفاده کنید.
سناریویی را در نظر بگیرید که نیاز دارید یک تابع ریاضی پیچیده را روی یک ستون اعمال کنید. از استفاده از apply() با یک تابع سفارشی پایتون خودداری کنید مگر اینکه واقعاً ضروری باشد، زیرا این کار به یک حلقه پایتون باز میگردد. در عوض، از توابع داخلی NumPy استفاده کنید که در C پیادهسازی شدهاند:
# ناکارآمد: استفاده از apply با لامبدا
# df['sales_normalized'] = df['sales'].apply(lambda x: np.log1p(x))
# کارآمد: عملیات برداری NumPy
df['sales_normalized'] = np.log1p(df['sales'])
با انتقال محاسبات به سطح آرایههای C، میتوانید بهبودهای مرتبه بزرگی در زمان اجرا مشاهده کنید، به ویژه با مجموعه دادههایی که حاوی میلیونها ردیف هستند.
مدیریت دادههای گمشده و تبدیل نوع
دادههای دنیای واقعی به ندرت تمیز هستند. Pandas روشهای قوی برای مدیریت مقادیر NaN (عدد نیست) ارائه میدهد. توسعهدهندگان باید با dropna() برای حذف رکوردهای ناقص و fillna() برای جایگزینی مقادیر گمشده با میانگین، میانه یا روشهای پر کردن رو به جلو آشنا باشند.
علاوه بر این، اطمینان از صحت انواع داده برای کارایی حافظه حیاتی است. استفاده از df.info() به شما امکان میدهد مصرف حافظه را بررسی کنید. تبدیل رشتههای دستهای به نوع داده category یا استفاده از اعداد صحیح قابل حذف Int64 به جای اعداد اعشاری استاندارد میتواند به طور چشمگیری ردپای حافظه DataFrames شما را کاهش دهد.
نتیجهگیری
تسلط بر Pandas و NumPy سفری از بارگذاری دادههای پایه به پایپلاینهای داده پیچیده و بهینهشده است. با درک معماری زیربنایی پخش آرایههای NumPy و همترازی مبتنی بر شاخص در Pandas، توسعهدهندگان میتوانند کدی بنویسند که نه تنها خوانا بلکه دارای عملکرد بالا باشد. همانطور که در سفر علم داده خود ادامه میدهید، همیشه کد خود را پروفایل کنید، عملیات برداری را بر حلقهها ترجیح دهید و از اکوسیستم غنی افزونههایی که بر این کتابخانههای هسته ساخته شدهاند استفاده کنید.