Pandas چیست؟ آموزش کامل تحلیل و پاکسازی داده با پایتون
آموزش کامل Pandas از نصب و ساخت DataFrame تا خواندن CSV و Excel، پاکسازی داده، مدیریت Missing Value، فیلتر، GroupBy، Merge، Pivot، پردازش فایلهای بزرگ و اتصال گزارش به API درواره.
Pandas یکی از مهمترین کتابخانههای پایتون برای خواندن، پاکسازی، تبدیل و تحلیل دادههای جدولی است. اگر با فایلهای CSV و Excel، دادههای دیتابیس، گزارش فروش، اطلاعات کاربران، خروجی نرمافزارها یا نتایج مدلهای هوش مصنوعی کار میکنید، یادگیری Pandas تقریباً ضروری است.
بخش بزرگی از زمان یک پروژه داده صرف ساخت مدل نمیشود؛ بلکه به آمادهسازی داده، اصلاح نوع ستونها، حذف رکوردهای تکراری، مدیریت مقادیر گمشده، اتصال جدولها و تولید گزارش اختصاص پیدا میکند. Pandas این عملیات را با ساختارهایی مانند DataFrame و Series در اختیار توسعهدهنده قرار میدهد.
در این آموزش، Pandas را از مفاهیم پایه تا ساخت یک Pipeline عملی تحلیل داده بررسی میکنیم. کدها بهگونهای نوشته شدهاند که بتوانید آنها را داخل Jupyter Notebook، Google Colab، VS Code یا یک پروژه Python معمولی اجرا کنید.
Pandas چیست؟
Pandas یک کتابخانه متنباز برای کار با دادههای ساختاریافته در Python است. این کتابخانه دو ساختار اصلی دارد:
Seriesبرای دادههای یکبعدیDataFrameبرای دادههای دوبعدی دارای سطر و ستون
یک DataFrame را میتوان مشابه یک جدول Excel یا نتیجه Query دیتابیس تصور کرد؛ با این تفاوت که تمام عملیات آن از طریق کد قابل اجرا، تکرار و اتوماسیون است.
نمونه یک DataFrame:
import pandas as pd
data = pd.DataFrame(
{
"product": [
"محصول اول",
"محصول دوم",
"محصول سوم",
],
"quantity": [
3,
5,
2,
],
"unit_price": [
120_000,
85_000,
210_000,
],
}
)
print(data)
خروجی:
product quantity unit_price
0 محصول اول 3 120000
1 محصول دوم 5 85000
2 محصول سوم 2 210000
Pandas چه کاربردهایی دارد؟
Pandas در پروژههای مختلف استفاده میشود:
- خواندن فایل CSV
- خواندن و ساخت فایل Excel
- دریافت داده از JSON
- تحلیل خروجی دیتابیس
- پاکسازی دادههای ناقص
- اصلاح نوع ستونها
- پردازش متن
- حذف رکوردهای تکراری
- گروهبندی و Aggregation
- ساخت Pivot Table
- اتصال چند جدول با Merge
- تحلیل دادههای زمانی
- آمادهسازی داده برای Machine Learning
- تولید گزارشهای آماری
- آمادهسازی داده برای مدلهای هوش مصنوعی
- پردازش فایلهای بزرگ بهصورت Chunk
تفاوت Pandas با Excel چیست؟
Pandas و Excel هر دو برای کار با داده جدولی استفاده میشوند، اما روش استفاده از آنها متفاوت است.
| ویژگی | Pandas | Excel |
|---|---|---|
| محیط کار | کد پایتون | رابط گرافیکی |
| تکرارپذیری | بسیار بالا | وابسته به نحوه طراحی فایل |
| اتوماسیون | قدرتمند | محدودتر |
| پردازش فایل بزرگ | مناسبتر | محدودتر |
| اتصال به API | مستقیم | معمولاً با ابزار جانبی |
| اتصال به دیتابیس | ساده | محدودتر |
| ثبت تاریخچه تغییرات | با Git | دشوارتر |
| مناسب کاربر غیرفنی | کمتر | بیشتر |
| ساخت Pipeline | بسیار مناسب | محدود |
| استفاده در Backend | بله | خیر |
Excel برای بررسی دستی و گزارشهای تعاملی مناسب است. Pandas برای پردازش تکرارشونده، اتوماسیون، تحلیل قابلبازتولید و اتصال به نرمافزار انتخاب بهتری است.
در بسیاری از پروژهها میتوان از هر دو استفاده کرد: پردازش اصلی با Pandas انجام شود و خروجی نهایی برای بررسی کاربر در Excel قرار بگیرد.
نصب Pandas
ابتدا Python را نصب کنید و سپس در Terminal اجرا کنید:
pip install pandas
برای استفاده از Excel و Parquet:
pip install pandas openpyxl pyarrow
برای رسم نمودار:
pip install matplotlib
نصب تمام وابستگیهای این آموزش:
pip install pandas numpy openpyxl pyarrow matplotlib requests
بررسی نسخه نصبشده:
python -c "import pandas; print(pandas.__version__)"
این آموزش تغییرات مهم Pandas 3 را نیز در نظر میگیرد.
ساخت Virtual Environment
ایجاد محیط مجازی:
python -m venv .venv
فعالسازی در Windows PowerShell:
.venv\Scripts\Activate.ps1
فعالسازی در Linux و macOS:
source .venv/bin/activate
سپس:
python -m pip install --upgrade pip
python -m pip install pandas numpy openpyxl pyarrow matplotlib requests
ساختار Series
یک Series شامل مجموعهای از مقادیر و یک Index است:
import pandas as pd
prices = pd.Series(
[
120_000,
85_000,
210_000,
],
index=[
"product_a",
"product_b",
"product_c",
],
name="price",
)
print(prices)
دسترسی با Label:
print(
prices.loc["product_b"]
)
دسترسی با موقعیت:
print(
prices.iloc[1]
)
تفاوت مهم:
locبر اساس Label کار میکند.ilocبر اساس موقعیت عددی کار میکند.
ساخت DataFrame
از Dictionary:
data = pd.DataFrame(
{
"order_id": [
1001,
1002,
1003,
],
"city": [
"تهران",
"شیراز",
"اصفهان",
],
"quantity": [
2,
3,
1,
],
}
)
از فهرست Dictionaryها:
records = [
{
"order_id": 1001,
"city": "تهران",
"quantity": 2,
},
{
"order_id": 1002,
"city": "شیراز",
"quantity": 3,
},
]
data = pd.DataFrame(records)
از فهرستهای دوبعدی:
data = pd.DataFrame(
[
[1001, "تهران", 2],
[1002, "شیراز", 3],
],
columns=[
"order_id",
"city",
"quantity",
],
)
مشاهده اولیه داده
پس از خواندن هر دیتاست، قبل از انجام تحلیل این دستورات را اجرا کنید:
print(
data.head()
)
print(
data.tail()
)
print(
data.shape
)
print(
data.columns
)
print(
data.dtypes
)
print(
data.info()
)
توضیح:
| دستور | کاربرد |
|---|---|
head() | نمایش چند رکورد اول |
tail() | نمایش چند رکورد آخر |
shape | تعداد سطر و ستون |
columns | نام ستونها |
dtypes | نوع هر ستون |
info() | خلاصه ساختار و حافظه |
describe() | آمار توصیفی |
آمار ستونهای عددی:
print(
data.describe()
)
آمار تمام ستونها:
print(
data.describe(
include="all"
)
)
خواندن فایل CSV با Pandas
سادهترین حالت:
import pandas as pd
data = pd.read_csv(
"sales.csv"
)
متد read_csv میتواند فایل CSV را به DataFrame تبدیل کند و قابلیتهایی مانند تعیین Separator، نوع ستون، مقادیر گمشده، Encoding و خواندن Chunk را ارائه میدهد. فهرست کامل پارامترها در مستندات رسمی read_csv موجود است.
خواندن CSV فارسی
برای فایل UTF-8:
data = pd.read_csv(
"sales.csv",
encoding="utf-8",
)
اگر فایل با BOM ذخیره شده باشد:
data = pd.read_csv(
"sales.csv",
encoding="utf-8-sig",
)
اگر جداکننده Semicolon باشد:
data = pd.read_csv(
"sales.csv",
sep=";",
encoding="utf-8-sig",
)
مشخصکردن مقادیر گمشده
data = pd.read_csv(
"sales.csv",
na_values=[
"",
"NULL",
"null",
"N/A",
"-",
"نامشخص",
],
)
خواندن فقط ستونهای ضروری
data = pd.read_csv(
"sales.csv",
usecols=[
"order_id",
"order_date",
"city",
"quantity",
"unit_price",
],
)
مشخصکردن نوع ستون
data = pd.read_csv(
"sales.csv",
dtype={
"order_id": "string",
"city": "string",
"quantity": "Int64",
},
)
اگر شناسهای ممکن است صفر ابتدایی داشته باشد، آن را عددی نخوانید:
data = pd.read_csv(
"customers.csv",
dtype={
"customer_id": "string",
"postal_code": "string",
},
)
خواندن فایل Excel
data = pd.read_excel(
"sales.xlsx"
)
انتخاب Sheet:
data = pd.read_excel(
"sales.xlsx",
sheet_name="Sales",
)
خواندن چند Sheet:
sheets = pd.read_excel(
"sales.xlsx",
sheet_name=[
"Sales",
"Customers",
],
)
sales = sheets["Sales"]
customers = sheets["Customers"]
برای فایلهای .xlsx معمولاً به openpyxl نیاز دارید:
pip install openpyxl
Pandas از چند Engine برای فرمتهای مختلف Excel پشتیبانی میکند. جزئیات فرمتها در راهنمای ورودی و خروجی Pandas ارائه شده است.
ذخیره CSV و Excel
ذخیره CSV با پشتیبانی مناسب از متن فارسی:
data.to_csv(
"clean_sales.csv",
index=False,
encoding="utf-8-sig",
)
ذخیره Excel:
data.to_excel(
"clean_sales.xlsx",
index=False,
sheet_name="Sales",
)
ذخیره چند DataFrame در چند Sheet:
with pd.ExcelWriter(
"report.xlsx",
engine="openpyxl",
) as writer:
data.to_excel(
writer,
sheet_name="Clean Data",
index=False,
)
summary.to_excel(
writer,
sheet_name="Summary",
index=False,
)
خواندن JSON
اگر فایل شامل فهرستی از Objectها باشد:
data = pd.read_json(
"records.json"
)
از پاسخ API:
import requests
import pandas as pd
response = requests.get(
"https://example.com/api/items",
timeout=30,
)
response.raise_for_status()
payload = response.json()
data = pd.DataFrame(
payload["items"]
)
پیش از ساخت DataFrame باید ساختار پاسخ API را بررسی کنید؛ زیرا ممکن است داده اصلی داخل کلیدی مانند data، results یا items قرار گرفته باشد.
پروژه عملی تحلیل داده فروش
فرض کنید فایل sales.csv چنین ستونهایی دارد:
order_id,order_date,customer_id,city,category,quantity,unit_price,status
1001,2026-07-01,C001, تهران ,اشتراک,2,350000,completed
1002,2026-07-01,C002,شیراز,اعتبار,1,500000,completed
1003,2026-07-02,C003,اصفهان,اشتراک,3,350000,pending
1004,2026-07-02,C001,تهران,اعتبار,2,500000,completed
1004,2026-07-02,C001,تهران,اعتبار,2,500000,completed
1005,invalid-date,C004,مشهد,اشتراک,,350000,cancelled
1006,2026-07-03,C005,شیراز,اعتبار,1,,completed
خواندن فایل:
import pandas as pd
data = pd.read_csv(
"sales.csv",
encoding="utf-8-sig",
dtype={
"order_id": "string",
"customer_id": "string",
"city": "string",
"category": "string",
"status": "string",
},
)
استانداردسازی نام ستونها
نام ستونها را پاک و یکدست کنید:
data.columns = (
data.columns
.str.strip()
.str.lower()
.str.replace(
" ",
"_",
regex=False,
)
)
اگر نام فارسی دارید:
column_mapping = {
"شماره سفارش": "order_id",
"تاریخ سفارش": "order_date",
"شهر": "city",
"تعداد": "quantity",
"قیمت واحد": "unit_price",
}
data = data.rename(
columns=column_mapping
)
بررسی Schema ورودی
قبل از تحلیل، وجود ستونهای ضروری را کنترل کنید:
required_columns = {
"order_id",
"order_date",
"customer_id",
"city",
"category",
"quantity",
"unit_price",
"status",
}
missing_columns = (
required_columns
- set(data.columns)
)
if missing_columns:
raise ValueError(
"Missing required columns: "
f"{sorted(missing_columns)}"
)
بررسی ستونهای اضافی:
unexpected_columns = (
set(data.columns)
- required_columns
)
if unexpected_columns:
print(
"Unexpected columns:",
sorted(
unexpected_columns
),
)
وجود ستون اضافه همیشه خطا نیست؛ اما باید مشخص شود Pipeline چگونه با آن برخورد میکند.
پاکسازی ستونهای متنی
حذف فاصله ابتدا و انتها:
text_columns = [
"city",
"category",
"status",
]
for column in text_columns:
data[column] = (
data[column]
.astype("string")
.str.strip()
)
تبدیل متن انگلیسی به حروف کوچک:
data["status"] = (
data["status"]
.str.lower()
)
یکسانسازی مقدارها:
status_mapping = {
"complete": "completed",
"done": "completed",
"cancel": "cancelled",
"canceled": "cancelled",
}
data["status"] = (
data["status"]
.replace(status_mapping)
)
یکسانسازی حروف فارسی و عربی:
def normalize_persian_text(
series: pd.Series,
) -> pd.Series:
return (
series
.astype("string")
.str.replace(
"ي",
"ی",
regex=False,
)
.str.replace(
"ك",
"ک",
regex=False,
)
.str.replace(
"\u200c",
" ",
regex=False,
)
.str.replace(
r"\s+",
" ",
regex=True,
)
.str.strip()
)
data["city"] = (
normalize_persian_text(
data["city"]
)
)
در بعضی پروژهها تبدیل نیمفاصله به فاصله مناسب نیست. سیاست Normalization باید با نیاز جستوجو، نمایش و Matching هماهنگ شود.
تبدیل نوع ستونهای عددی
اگر مقادیر عددی بهصورت String وارد شدهاند:
data["quantity"] = pd.to_numeric(
data["quantity"],
errors="coerce",
)
data["unit_price"] = pd.to_numeric(
data["unit_price"],
errors="coerce",
)
پارامتر errors="coerce" مقادیر غیرقابلتبدیل را به مقدار گمشده تبدیل میکند. این روش مانع توقف Pipeline میشود، اما باید تعداد خطاهای تبدیل گزارش شود:
invalid_quantity_count = (
data["quantity"]
.isna()
.sum()
)
invalid_price_count = (
data["unit_price"]
.isna()
.sum()
)
print(
"Invalid quantity values:",
invalid_quantity_count,
)
print(
"Invalid price values:",
invalid_price_count,
)
تبدیل به نوع Nullable Integer:
data["quantity"] = (
data["quantity"]
.astype("Int64")
)
نوع Int64 با حرف بزرگ، نوع Nullable Integer در Pandas است و میتواند مقدار گمشده داشته باشد.
تبدیل تاریخ
data["order_date"] = pd.to_datetime(
data["order_date"],
errors="coerce",
)
بررسی تاریخهای نامعتبر:
invalid_dates = data.loc[
data["order_date"].isna(),
[
"order_id",
"order_date",
],
]
print(invalid_dates)
اگر فرمت تاریخ دقیق است:
data["order_date"] = pd.to_datetime(
data["order_date"],
format="%Y-%m-%d",
errors="coerce",
)
مشخصکردن فرمت میتواند تبدیل تاریخ را قابلپیشبینیتر کند.
مدیریت Missing Value
تعداد مقادیر گمشده هر ستون:
missing_report = (
data.isna()
.sum()
.sort_values(
ascending=False
)
)
print(missing_report)
درصد مقادیر گمشده:
missing_percentage = (
data.isna()
.mean()
.mul(100)
.round(2)
.sort_values(
ascending=False
)
)
print(missing_percentage)
حذف رکوردهای ناقص
اگر وجود مقدار برای چند ستون ضروری است:
clean_data = data.dropna(
subset=[
"order_id",
"order_date",
"quantity",
"unit_price",
]
)
جایگزینی با Median
median_price = (
data["unit_price"]
.median()
)
data["unit_price"] = (
data["unit_price"]
.fillna(median_price)
)
جایگزینی متن گمشده
data["city"] = (
data["city"]
.fillna("نامشخص")
)
نباید تمام Missing Valueها را بدون بررسی حذف یا جایگزین کرد. مقدار گمشده گاهی خودش حامل اطلاعات است.
راهنمای کامل رفتار مقادیر گمشده در مستندات Missing Data در Pandas موجود است.
شناسایی رکوردهای تکراری
تعداد تمام ردیفهای تکراری:
duplicate_count = (
data.duplicated()
.sum()
)
print(
"Duplicate rows:",
duplicate_count,
)
بررسی تکرار بر اساس شناسه:
duplicate_orders = data.loc[
data.duplicated(
subset=["order_id"],
keep=False,
)
].sort_values(
"order_id"
)
print(duplicate_orders)
حذف تکراریها:
data = data.drop_duplicates(
subset=["order_id"],
keep="last",
)
انتخاب first یا last باید بر اساس معنی داده باشد. اگر رکوردها نسخههای مختلف یک سفارش هستند، ممکن است لازم باشد ابتدا آنها را بر اساس زمان بهروزرسانی مرتب کنید.
data = (
data
.sort_values(
"updated_at"
)
.drop_duplicates(
subset=["order_id"],
keep="last",
)
)
فیلترکردن داده با Boolean Mask
سفارشهای تکمیلشده:
completed_orders = data.loc[
data["status"].eq(
"completed"
)
]
سفارشهای یک شهر:
tehran_orders = data.loc[
data["city"].eq(
"تهران"
)
]
ترکیب چند شرط:
selected_orders = data.loc[
data["status"].eq(
"completed"
)
& data["city"].isin(
[
"تهران",
"شیراز",
]
)
& data["quantity"].ge(2)
]
استفاده از between:
selected_orders = data.loc[
data["unit_price"].between(
300_000,
600_000,
inclusive="both",
)
]
انتخاب ستونها
report_columns = data.loc[
:,
[
"order_id",
"order_date",
"city",
"quantity",
"unit_price",
],
]
دسترسی به سطرها بر اساس موقعیت:
first_ten_rows = data.iloc[
0:10
]
ساخت ستون جدید
محاسبه مبلغ هر ردیف:
data["revenue"] = (
data["quantity"]
* data["unit_price"]
)
ساخت ستون Boolean:
data["is_completed"] = (
data["status"]
.eq("completed")
)
استخراج سال و ماه:
data["year"] = (
data["order_date"]
.dt.year
)
data["month"] = (
data["order_date"]
.dt.month
)
data["year_month"] = (
data["order_date"]
.dt.to_period("M")
.astype("string")
)
ساخت دسته مبلغ:
data["revenue_level"] = pd.cut(
data["revenue"],
bins=[
0,
500_000,
1_000_000,
float("inf"),
],
labels=[
"low",
"medium",
"high",
],
include_lowest=True,
)
نکته مهم Pandas 3 و Copy-on-Write
از Pandas 3، رفتار Copy-on-Write بهصورت پیشفرض فعال است. خروجی عملیات Indexing از دید کاربر مانند یک Copy رفتار میکند و Chained Assignment دیگر روش معتبری برای تغییر DataFrame اصلی نیست.
کد نامناسب:
data[
data["city"] == "تهران"
]["status"] = "completed"
روش صحیح:
data.loc[
data["city"] == "تهران",
"status",
] = "completed"
طبق راهنمای تغییرات Pandas 3، Chained Assignment دیگر DataFrame اصلی را تغییر نمیدهد. استفاده مستقیم از loc هم خواناتر است و هم رفتار قابلپیشبینیتری دارد.
نوع String در Pandas 3
در Pandas 3، دادههای متنی بهصورت پیشفرض با نوع str تشخیص داده میشوند. در نسخههای قدیمیتر معمولاً نوع object مشاهده میشد.
ساخت Series متنی:
names = pd.Series(
[
"تهران",
"شیراز",
None,
],
dtype="string",
)
پاکسازی متن:
names = (
names
.str.strip()
.str.lower()
)
مستندات Pandas استفاده از StringDtype را برای دادههای متنی توصیه میکند. جزئیات رفتار جدید در راهنمای دادههای متنی Pandas آمده است.
مرتبسازی داده
مرتبسازی بر اساس مبلغ:
data = data.sort_values(
"revenue",
ascending=False,
)
مرتبسازی بر اساس چند ستون:
data = data.sort_values(
by=[
"city",
"revenue",
],
ascending=[
True,
False,
],
)
مرتبسازی بر اساس Index:
data = data.sort_index()
GroupBy در Pandas
محاسبه مجموع مبلغ بر اساس شهر:
city_revenue = (
data
.groupby(
"city",
as_index=False,
)
.agg(
total_revenue=(
"revenue",
"sum",
)
)
)
محاسبه چند معیار:
city_summary = (
data
.groupby(
"city",
as_index=False,
)
.agg(
order_count=(
"order_id",
"nunique",
),
total_quantity=(
"quantity",
"sum",
),
total_revenue=(
"revenue",
"sum",
),
average_order_value=(
"revenue",
"mean",
),
median_order_value=(
"revenue",
"median",
),
)
.sort_values(
"total_revenue",
ascending=False,
)
)
GroupBy از الگوی Split، Apply و Combine استفاده میکند: داده به گروهها تقسیم میشود، یک عملیات روی هر گروه انجام میشود و نتیجهها دوباره ترکیب میشوند. این ساختار در مستندات GroupBy در Pandas توضیح داده شده است.
محاسبه سهم هر گروه
city_summary[
"revenue_share"
] = (
city_summary[
"total_revenue"
]
/ city_summary[
"total_revenue"
].sum()
)
نمایش درصد:
city_summary[
"revenue_share_percent"
] = (
city_summary[
"revenue_share"
]
.mul(100)
.round(2)
)
Pivot Table
ساخت گزارش شهر و دسته محصول:
pivot_report = pd.pivot_table(
data,
index="city",
columns="category",
values="revenue",
aggfunc="sum",
fill_value=0,
margins=True,
margins_name="مجموع",
)
چند معیار همزمان:
pivot_report = pd.pivot_table(
data,
index="city",
columns="category",
values=[
"quantity",
"revenue",
],
aggfunc={
"quantity": "sum",
"revenue": "sum",
},
fill_value=0,
)
راهنمای کامل این عملیات در مستندات Reshaping و Pivot Table موجود است.
اتصال دو DataFrame با Merge
فرض کنید اطلاعات مشتریان در فایل دیگری قرار دارد:
customers = pd.DataFrame(
{
"customer_id": [
"C001",
"C002",
"C003",
"C004",
"C005",
],
"customer_segment": [
"regular",
"new",
"regular",
"new",
"business",
],
}
)
اتصال سفارشها به مشتریان:
merged_data = data.merge(
customers,
on="customer_id",
how="left",
validate="many_to_one",
indicator=True,
)
پارامتر validate="many_to_one" بررسی میکند هر مشتری در جدول سمت راست حداکثر یک رکورد داشته باشد.
بررسی رکوردهای بدون تطبیق:
unmatched_rows = merged_data.loc[
merged_data["_merge"]
.ne("both")
]
print(unmatched_rows)
حذف ستون کمکی:
merged_data = (
merged_data
.drop(
columns=["_merge"]
)
)
استفاده از validate اهمیت زیادی دارد. Merge روی کلیدهای تکراری میتواند تعداد ردیفها را بهطور غیرمنتظره افزایش دهد و حتی باعث مصرف شدید حافظه شود. مستندات Merge در Pandas استفاده از validate را برای کنترل یکتایی کلیدها توضیح میدهد.
انواع Merge
مقدار how | رفتار |
|---|---|
inner | فقط رکوردهای مشترک |
left | تمام رکوردهای جدول چپ |
right | تمام رکوردهای جدول راست |
outer | تمام رکوردهای هر دو جدول |
cross | تمام ترکیبهای ممکن |
اتصال عمودی DataFrameها با Concat
اگر فایل هر ماه جدا باشد:
june_data = pd.read_csv(
"sales_2026_06.csv"
)
july_data = pd.read_csv(
"sales_2026_07.csv"
)
all_sales = pd.concat(
[
june_data,
july_data,
],
ignore_index=True,
)
اگر ستونهای دو فایل متفاوت باشند، Pandas مجموعه ستونها را ترکیب میکند و برای ستونهای غایب مقدار Missing قرار میدهد. بهتر است Schema فایلها را قبل از Concat اعتبارسنجی کنید.
استفاده از Query
minimum_revenue = 500_000
selected = data.query(
"status == 'completed' "
"and revenue >= @minimum_revenue"
)
روش query برای شرطهای خوانا مفید است، اما در نام ستونهای دارای فاصله یا کاراکترهای خاص باید دقت بیشتری داشت.
کار با تاریخ و زمان
فیلتر یک بازه زمانی:
start_date = pd.Timestamp(
"2026-07-01"
)
end_date = pd.Timestamp(
"2026-07-31"
)
july_data = data.loc[
data["order_date"].between(
start_date,
end_date,
inclusive="both",
)
]
تجمیع روزانه:
daily_summary = (
data
.set_index(
"order_date"
)
.resample("D")
.agg(
total_revenue=(
"revenue",
"sum",
),
order_count=(
"order_id",
"nunique",
),
)
.reset_index()
)
تجمیع هفتگی:
weekly_summary = (
data
.set_index(
"order_date"
)
.resample("W")
.agg(
total_revenue=(
"revenue",
"sum",
)
)
.reset_index()
)
میانگین متحرک هفتروزه:
daily_summary[
"revenue_7d_average"
] = (
daily_summary[
"total_revenue"
]
.rolling(
window=7,
min_periods=1,
)
.mean()
)
رسم نمودار با Pandas
import matplotlib.pyplot as plt
plot_data = (
city_summary
.sort_values(
"total_revenue",
ascending=True,
)
)
plot_data.plot(
kind="barh",
x="city",
y="total_revenue",
legend=False,
figsize=(9, 6),
)
plt.xlabel(
"Total revenue"
)
plt.ylabel(
"City"
)
plt.title(
"Revenue by City"
)
plt.tight_layout()
plt.show()
برای نمودارهای حرفهایتر میتوانید از Matplotlib، Seaborn یا Plotly استفاده کنید.
چرا Vectorization بهتر از Loop و Apply است؟
کد کندتر:
revenues = []
for _, row in data.iterrows():
revenues.append(
row["quantity"]
* row["unit_price"]
)
data["revenue"] = revenues
روش Vectorized:
data["revenue"] = (
data["quantity"]
* data["unit_price"]
)
عملیات Vectorized معمولاً خواناتر و سریعتر است. از apply(axis=1) فقط زمانی استفاده کنید که عملیات موردنظر با متدهای داخلی و Vectorized قابل پیادهسازی نباشد.
کد قابلبهبود:
data["revenue"] = data.apply(
lambda row: (
row["quantity"]
* row["unit_price"]
),
axis=1,
)
نسخه بهتر:
data["revenue"] = (
data["quantity"]
* data["unit_price"]
)
ساخت Pipeline پاکسازی
بهتر است مراحل پردازش داخل Functionهای کوچک قرار بگیرند:
REQUIRED_COLUMNS = {
"order_id",
"order_date",
"customer_id",
"city",
"category",
"quantity",
"unit_price",
"status",
}
def normalize_columns(
data: pd.DataFrame,
) -> pd.DataFrame:
result = data.copy()
result.columns = (
result.columns
.str.strip()
.str.lower()
.str.replace(
" ",
"_",
regex=False,
)
)
return result
def validate_schema(
data: pd.DataFrame,
) -> None:
missing_columns = (
REQUIRED_COLUMNS
- set(data.columns)
)
if missing_columns:
raise ValueError(
"Missing columns: "
f"{sorted(missing_columns)}"
)
def clean_text_columns(
data: pd.DataFrame,
) -> pd.DataFrame:
result = data.copy()
text_columns = [
"city",
"category",
"status",
]
for column in text_columns:
result[column] = (
result[column]
.astype("string")
.str.replace(
"ي",
"ی",
regex=False,
)
.str.replace(
"ك",
"ک",
regex=False,
)
.str.replace(
r"\s+",
" ",
regex=True,
)
.str.strip()
)
result["status"] = (
result["status"]
.str.lower()
)
return result
def convert_types(
data: pd.DataFrame,
) -> pd.DataFrame:
result = data.copy()
result["order_date"] = (
pd.to_datetime(
result["order_date"],
errors="coerce",
)
)
result["quantity"] = (
pd.to_numeric(
result["quantity"],
errors="coerce",
)
)
result["unit_price"] = (
pd.to_numeric(
result["unit_price"],
errors="coerce",
)
)
return result
def remove_duplicates(
data: pd.DataFrame,
) -> pd.DataFrame:
return data.drop_duplicates(
subset=["order_id"],
keep="last",
)
def add_calculated_columns(
data: pd.DataFrame,
) -> pd.DataFrame:
result = data.copy()
result["revenue"] = (
result["quantity"]
* result["unit_price"]
)
result["year_month"] = (
result["order_date"]
.dt.to_period("M")
.astype("string")
)
return result
تابع اصلی:
def prepare_sales_data(
file_path: str,
) -> pd.DataFrame:
data = pd.read_csv(
file_path,
encoding="utf-8-sig",
dtype={
"order_id": "string",
"customer_id": "string",
},
)
data = normalize_columns(
data
)
validate_schema(
data
)
data = clean_text_columns(
data
)
data = convert_types(
data
)
data = remove_duplicates(
data
)
data = data.dropna(
subset=[
"order_id",
"order_date",
"quantity",
"unit_price",
]
)
data = add_calculated_columns(
data
)
return data.reset_index(
drop=True
)
استفاده:
clean_data = prepare_sales_data(
"sales.csv"
)
print(
clean_data.head()
)
ساخت گزارش کیفیت داده
def build_quality_report(
data: pd.DataFrame,
) -> dict:
return {
"rows": int(
len(data)
),
"columns": int(
len(data.columns)
),
"duplicate_rows": int(
data.duplicated().sum()
),
"missing_by_column": {
column: int(value)
for column, value in (
data.isna()
.sum()
.items()
)
},
"dtypes": {
column: str(dtype)
for column, dtype in (
data.dtypes.items()
)
},
}
استفاده:
quality_report = (
build_quality_report(
clean_data
)
)
print(
quality_report
)
این گزارش را میتوان همراه با نسخه فایل و زمان اجرا ذخیره کرد.
کنترل کیفیت با Assert
assert (
clean_data["order_id"]
.notna()
.all()
)
assert (
clean_data["order_id"]
.is_unique
)
assert (
clean_data["quantity"]
.ge(0)
.all()
)
assert (
clean_data["unit_price"]
.ge(0)
.all()
)
برای Pipelineهای Production بهتر است بهجای Assertهای پراکنده، Validation و خطاهای مشخص طراحی کنید؛ زیرا Assert جایگزین کامل سیستم اعتبارسنجی نیست.
خواندن فایلهای بزرگ با Chunk
Pandas یک ابزار In-memory است؛ بنابراین دیتاستهای بزرگتر از حافظه میتوانند مشکلساز شوند. مستندات Pandas نیز توضیح میدهد که بعضی عملیاتها Copyهای میانی ایجاد میکنند و حتی دیتاست کوچکتر از RAM ممکن است سنگین شود. راهکارها در راهنمای Scaling Pandas آمده است.
خواندن فایل در Chunkهای صد هزارردیفی:
chunks = pd.read_csv(
"large_sales.csv",
chunksize=100_000,
encoding="utf-8-sig",
)
پردازش مرحلهای:
partial_results = []
for chunk in chunks:
chunk.columns = (
chunk.columns
.str.strip()
.str.lower()
)
chunk["quantity"] = (
pd.to_numeric(
chunk["quantity"],
errors="coerce",
)
)
chunk["unit_price"] = (
pd.to_numeric(
chunk["unit_price"],
errors="coerce",
)
)
chunk = chunk.dropna(
subset=[
"quantity",
"unit_price",
]
)
chunk["revenue"] = (
chunk["quantity"]
* chunk["unit_price"]
)
partial_summary = (
chunk
.groupby(
"city",
as_index=False,
)
.agg(
total_revenue=(
"revenue",
"sum",
)
)
)
partial_results.append(
partial_summary
)
ترکیب نتایج:
final_summary = (
pd.concat(
partial_results,
ignore_index=True,
)
.groupby(
"city",
as_index=False,
)
.agg(
total_revenue=(
"total_revenue",
"sum",
)
)
)
این روش زمانی مناسب است که عملیات هر Chunk مستقل باشد. عملیاتهایی مانند حذف تکراری سراسری، Sort کامل یا بعضی Windowها به طراحی دقیقتری نیاز دارند.
کاهش مصرف حافظه
اندازه DataFrame:
memory_bytes = (
data.memory_usage(
deep=True
).sum()
)
memory_megabytes = (
memory_bytes
/ 1024**2
)
print(
f"Memory: "
f"{memory_megabytes:.2f} MB"
)
تبدیل ستون با مقادیر محدود به Category:
data["city"] = (
data["city"]
.astype("category")
)
data["status"] = (
data["status"]
.astype("category")
)
کاهش نوع عددی:
data["quantity"] = (
pd.to_numeric(
data["quantity"],
downcast="integer",
)
)
data["unit_price"] = (
pd.to_numeric(
data["unit_price"],
downcast="integer",
)
)
Downcast باید پس از بررسی محدوده مقادیر انجام شود تا Overflow ایجاد نشود.
استفاده از Parquet بهجای CSV
ذخیره Parquet:
data.to_parquet(
"clean_sales.parquet",
index=False,
)
خواندن:
data = pd.read_parquet(
"clean_sales.parquet"
)
Parquet یک فرمت ستونی است که معمولاً نوع داده را بهتر از CSV حفظ میکند و میتواند حجم کمتر و سرعت خواندن بالاتری داشته باشد. برای استفاده معمولاً به pyarrow نیاز دارید:
pip install pyarrow
خواندن فقط ستونهای ضروری:
data = pd.read_parquet(
"clean_sales.parquet",
columns=[
"order_date",
"city",
"revenue",
],
)
اتصال Pandas به دیتابیس
نمونه با SQLite:
import sqlite3
import pandas as pd
connection = sqlite3.connect(
"app.db"
)
query = """
SELECT
order_id,
order_date,
city,
quantity,
unit_price
FROM orders
WHERE status = ?
"""
data = pd.read_sql_query(
query,
connection,
params=[
"completed"
],
)
connection.close()
برای دیتابیسهای دیگر میتوانید از SQLAlchemy و Driver مناسب استفاده کنید.
در پروژه واقعی بهتر است Aggregationهای بزرگ و فیلترهای اولیه داخل دیتابیس انجام شوند و فقط داده ضروری وارد Pandas شود.
آمادهسازی داده برای یادگیری ماشین
فرض کنید ستون هدف target است:
feature_columns = [
"monthly_sessions",
"used_features",
"days_since_signup",
]
X = data[
feature_columns
]
y = data[
"target"
]
برای جلوگیری از Data Leakage:
- Feature نباید اطلاعات بعد از زمان Target را در خود داشته باشد.
- Preprocessing باید فقط روی Train Fit شود.
- Test نباید برای انتخاب Feature استفاده شود.
- تقسیم زمانی برای دادههای وابسته به زمان بررسی شود.
- شناسههای مستقیم معمولاً Feature مناسبی نیستند.
- ستون Target نباید داخل
Xباقی بماند.
تفاوت محاسبه با Pandas و توضیح با مدل زبانی
مدل زبانی برای جمع، میانگین و GroupBy دقیق جایگزین مناسبی برای Pandas نیست. معماری قابلاعتمادتر این است:
- فایل با Pandas خوانده شود.
- Schema و نوع ستونها بررسی شوند.
- محاسبات با کد قطعی انجام شوند.
- فقط نتیجه تجمیعی به مدل زبانی داده شود.
- مدل زبانی گزارش را به زبان قابلفهم تبدیل کند.
- اعداد خروجی دوباره با نتیجه Pandas تطبیق داده شوند.
در این معماری، Pandas محاسبه را انجام میدهد و مدل زبانی مسئول توضیح نتیجه است.
اتصال گزارش Pandas به API درواره
پس از محاسبه گزارش، میتوانید از API هوش مصنوعی درواره برای تولید یک خلاصه فارسی استفاده کنید.
تنظیم متغیرهای محیطی در Linux و macOS:
export DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
export DARVAREH_MODEL_ID="YOUR_MODEL_ID"
در Windows PowerShell:
$env:DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
$env:DARVAREH_MODEL_ID="YOUR_MODEL_ID"
ساخت گزارش تجمیعی:
summary = (
clean_data
.groupby(
"city",
as_index=False,
)
.agg(
order_count=(
"order_id",
"nunique",
),
total_quantity=(
"quantity",
"sum",
),
total_revenue=(
"revenue",
"sum",
),
)
.sort_values(
"total_revenue",
ascending=False,
)
)
تبدیل به JSON:
summary_json = (
summary.to_json(
orient="records",
force_ascii=False,
)
)
ارسال به درواره:
import os
import requests
api_key = os.environ[
"DARVAREH_API_KEY"
]
model_id = os.environ[
"DARVAREH_MODEL_ID"
]
response = requests.post(
"https://api.darvareh.ir/v1/chat/completions",
headers={
"Authorization": (
f"Bearer {api_key}"
),
"Content-Type": (
"application/json"
),
},
json={
"model": model_id,
"messages": [
{
"role": "system",
"content": (
"گزارش داده را فقط "
"بر اساس اعداد ورودی "
"توضیح بده. هیچ عدد، "
"علت یا نتیجه جدیدی "
"اختراع نکن."
),
},
{
"role": "user",
"content": f"""
داده تجمیعی فروش بر اساس شهر:
{summary_json}
یک گزارش کوتاه فارسی بنویس که شامل این موارد باشد:
1. بیشترین مبلغ مربوط به کدام شهر است؟
2. ترتیب شهرها بر اساس مبلغ چگونه است؟
3. برای هر ادعا عدد دقیق را ذکر کن.
4. اگر داده برای نتیجهگیری کافی نیست، شفاف بگو.
""",
},
],
"temperature": 0.1,
},
timeout=60,
)
response.raise_for_status()
result = response.json()
report_text = result[
"choices"
][0]["message"]["content"]
print(report_text)
شناسه مدل را از صفحه مدلها و قیمتهای درواره انتخاب کنید.
بهتر است داده خام دارای اطلاعات شخصی، شناسه مشتری، شماره تماس یا اطلاعات غیرضروری برای تولید گزارش ارسال نشود. در بیشتر موارد، ارسال داده تجمیعی کافی است.
اعتبارسنجی اعداد گزارش تولیدشده
مدل زبانی ممکن است در بازنویسی اعداد خطا کند. راه امنتر این است که اعداد مهم را در کد محاسبه و جداگانه نگهداری کنید:
top_city_row = (
summary.iloc[0]
)
verified_values = {
"top_city": str(
top_city_row["city"]
),
"top_revenue": int(
top_city_row[
"total_revenue"
]
),
"top_order_count": int(
top_city_row[
"order_count"
]
),
}
print(
verified_values
)
در خروجیهای حساس به عدد، میتوانید Template نهایی را با Python بسازید و از مدل زبانی فقط برای اصلاح متن توضیحی استفاده کنید.
ذخیره گزارش و Metadata
from pathlib import Path
import json
output_directory = Path(
"output"
)
output_directory.mkdir(
parents=True,
exist_ok=True,
)
clean_data.to_parquet(
output_directory
/ "clean_sales.parquet",
index=False,
)
summary.to_csv(
output_directory
/ "city_summary.csv",
index=False,
encoding="utf-8-sig",
)
ذخیره Metadata:
metadata = {
"source_file": "sales.csv",
"input_rows": int(
len(data)
),
"output_rows": int(
len(clean_data)
),
"summary_rows": int(
len(summary)
),
"columns": list(
clean_data.columns
),
}
with (
output_directory
/ "metadata.json"
).open(
"w",
encoding="utf-8",
) as file:
json.dump(
metadata,
file,
ensure_ascii=False,
indent=2,
)
خطاهای رایج Pandas
خطای No module named 'pandas'
python -m pip install pandas
بررسی:
python -m pip show pandas
نمایش نامناسب متن فارسی
فایل را با Encoding درست بخوانید:
data = pd.read_csv(
"file.csv",
encoding="utf-8-sig",
)
اگر نتیجه صحیح نبود، Encoding واقعی فایل را بررسی کنید. انتخاب تصادفی Encoding ممکن است متن را بدون خطای آشکار خراب کند.
خطای KeyError
احتمالاً نام ستون اشتباه است:
print(
data.columns.tolist()
)
فاصلههای اضافی را پاک کنید:
data.columns = (
data.columns
.str.strip()
)
خطای تبدیل String به عدد
data["amount"] = pd.to_numeric(
data["amount"],
errors="coerce",
)
سپس رکوردهای تبدیلنشده را بررسی کنید:
invalid_rows = data.loc[
data["amount"].isna()
]
نتیجه Merge بیشازحد بزرگ است
احتمالاً کلیدها در هر دو جدول تکراری هستند:
print(
left["id"].duplicated().sum()
)
print(
right["id"].duplicated().sum()
)
از validate استفاده کنید:
result = left.merge(
right,
on="id",
validate="many_to_one",
)
تغییر DataFrame اعمال نمیشود
در Pandas 3 از Chained Assignment استفاده نکنید:
data.loc[
condition,
"column",
] = value
مصرف حافظه بسیار بالا است
- فقط ستونهای ضروری را بخوانید.
- نوع ستونها را بهینه کنید.
- از Category استفاده کنید.
- فایل را Chunk به Chunk پردازش کنید.
- Parquet را بررسی کنید.
- Aggregation اولیه را در دیتابیس انجام دهید.
- در صورت بزرگترشدن داده، ابزارهای مناسبتر را ارزیابی کنید.
اشتباهات رایج در تحلیل داده با Pandas
شروع تحلیل قبل از بررسی Schema
ابتدا نام ستون، نوع داده، Missing Value و یکتایی کلیدها را بررسی کنید.
حذف تمام Missing Valueها
این کار ممکن است بخش بزرگی از داده یا یک الگوی مهم را حذف کند.
استفاده از میانگین برای همه ستونها
Median، Mode، مقدار ثابت یا نگهداری Missing Value ممکن است در بعضی ستونها مناسبتر باشد.
استفاده زیاد از apply(axis=1)
ابتدا روشهای Vectorized را بررسی کنید.
Merge بدون validate
ممکن است تعداد رکوردها بدون اطلاع شما چند برابر شود.
استفاده از شناسه بهعنوان عدد
کد مشتری، کد پستی و شماره سفارش معمولاً اندازهگیری عددی نیستند و بهتر است String باشند.
تغییر دستی فایل خروجی
اگر خروجی Pipeline بهصورت دستی اصلاح شود، تکرارپذیری از بین میرود. اصلاح باید در کد Pipeline انجام شود.
ارسال کل دیتاست به مدل زبانی
برای توضیح گزارش معمولاً داده تجمیعی کافی است. ارسال کل فایل هزینه و ریسک خطا را افزایش میدهد.
چکلیست پروژه Pandas
- Encoding فایل مشخص شده است.
- Schema ورودی اعتبارسنجی میشود.
- نام ستونها استاندارد شدهاند.
- شناسهها بهصورت String خوانده میشوند.
- ستونهای عددی با کنترل خطا تبدیل شدهاند.
- تاریخهای نامعتبر گزارش میشوند.
- Missing Valueها بر اساس معنی ستون مدیریت شدهاند.
- رکوردهای تکراری بررسی شدهاند.
- Merge با
validateانجام میشود. - از Chained Assignment استفاده نمیشود.
- عملیات Vectorized بر Loop اولویت دارد.
- خروجی با فرمت مناسب ذخیره میشود.
- Metadata پردازش نگهداری میشود.
- فایلهای بزرگ بهصورت Chunk پردازش میشوند.
- داده غیرضروری برای مدل زبانی ارسال نمیشود.
- اعداد گزارش تولیدشده اعتبارسنجی میشوند.
سؤالات متداول
Pandas چیست؟
Pandas یک کتابخانه Python برای خواندن، پاکسازی، تبدیل، اتصال و تحلیل دادههای جدولی است.
DataFrame چیست؟
DataFrame یک ساختار دوبعدی شامل سطر، ستون، Index و نوع داده است. این ساختار شبیه جدول Excel یا نتیجه Query دیتابیس است.
تفاوت Series و DataFrame چیست؟
Series معمولاً یک ساختار یکبعدی و DataFrame یک ساختار دوبعدی شامل چند Series است.
آیا Pandas برای یادگیری ماشین لازم است؟
اجباری نیست، اما در بسیاری از پروژههای Machine Learning برای آمادهسازی، پاکسازی و بررسی داده استفاده میشود.
آیا Pandas میتواند فایل Excel را بخواند؟
بله. با read_excel میتوان فایلهای Excel را خواند. برای فایل .xlsx معمولاً کتابخانه openpyxl نیز لازم است.
آیا Pandas برای فایلهای بسیار بزرگ مناسب است؟
Pandas اساساً برای پردازش In-memory طراحی شده است. برای فایل بزرگ میتوان از chunksize، Parquet، بهینهسازی نوع ستونها یا ابزارهای پردازش توزیعشده استفاده کرد.
تفاوت loc و iloc چیست؟
loc بر اساس Label و iloc بر اساس موقعیت عددی داده را انتخاب میکند.
تفاوت merge و concat چیست؟
merge جدولها را بر اساس کلید متصل میکند. concat معمولاً DataFrameها را در امتداد سطر یا ستون کنار هم قرار میدهد.
آیا Pandas متن فارسی را پشتیبانی میکند؟
بله. برای جلوگیری از خرابی متن باید Encoding فایل، نوع String و Normalization حروف فارسی بهدرستی مدیریت شوند.
آیا Pandas میتواند به API متصل شود؟
Pandas مستقیماً Client کامل HTTP نیست، اما میتوانید با requests داده API را دریافت و سپس به DataFrame تبدیل کنید.
آیا میتوان Pandas را با API درواره ترکیب کرد؟
بله. محاسبات با Pandas انجام میشوند و نتیجه تجمیعی میتواند از طریق API درواره به یک مدل زبانی ارسال شود تا گزارش فارسی تولید شود.
آیا مدل زبانی میتواند جای Pandas را بگیرد؟
برای محاسبات دقیق، قابلتکرار و قابلآزمون بهتر است از Pandas یا ابزار محاسباتی مشابه استفاده شود. مدل زبانی بیشتر برای درک درخواست، تولید کد و توضیح نتیجه مناسب است.
جمعبندی
Pandas یکی از پایهایترین ابزارهای برنامهنویسی داده در Python است. با یادگیری DataFrame، پاکسازی متن، تبدیل نوع داده، مدیریت Missing Value، GroupBy، Merge، Pivot Table و پردازش Chunk میتوانید بخش بزرگی از Workflowهای تحلیل داده را پیادهسازی کنید.
مهمترین مهارت در Pandas حفظکردن تعداد زیادی متد نیست؛ بلکه طراحی یک Pipeline قابلاعتماد است. Pipeline مناسب باید ورودی را اعتبارسنجی کند، خطاهای تبدیل را گزارش دهد، محاسبات را بهصورت قابلتکرار انجام دهد و Metadata خروجی را نگهداری کند.
برای ساخت سیستمهای هوشمند، بهتر است محاسبات دقیق را با Pandas انجام دهید و از مدل زبانی برای تحلیل متن، توضیح نتایج و تولید گزارش استفاده کنید. این تفکیک مسئولیت، دقت و قابلیت کنترل سیستم را افزایش میدهد.
برای افزودن مدلهای زبانی به پروژههای تحلیل داده میتوانید از API هوش مصنوعی درواره استفاده کنید. برای انتخاب Model ID و مشاهده قیمتهای بهروز نیز صفحه مدلها و قیمتهای درواره را ببینید.
مقالات مرتبط
- تحلیل فایل CSV با هوش مصنوعی؛ ساخت AI Data Analyst
- هوش مصنوعی برای Excel و تحلیل داده
- رسم نمودار با هوش مصنوعی از داده و متن
- تبدیل متن به جدول با هوش مصنوعی
- آموزش هوش مصنوعی با پایتون و API درواره
- راهنمای ارزیابی مدلهای هوش مصنوعی و Evals
- آموزش دریافت API Key هوش مصنوعی
برای مطالعه شرایط استفاده و محدودیتهای مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.