Pandas: تجميع حسب المجموعة
آخر تحديث: 2026-08-26
تجميع المجموعات هو جوهر تحليل البيانات — عرض المبيعات حسب المنطقة، حساب متوسط الأسعار حسب الفئة، حساب الطلبات حسب الشهر — كلها تعود إلى "تقسيم، حساب، دمج." يقوم Pandas بتنفيذ نموذج التقسيم-التطبيق-الدمج الكلاسيكي. في هذا الدرس، ستساعدك مخططات Mermaid على فهم العملية بالكامل، وستتقن العمليات الرئيسية الثلاث: agg / transform / filter.
1. ماذا ستتعلم
- ❶ كيف يعمل groupby (القسمة-التطبيق-الدمج)
- ❷ دوال التجميع (sum/mean/count/max/min)
- ❸ تجميعات متعددة ودوال مخصصة باستخدام agg
- ❹ التحويل داخل المجموعات باستخدام transform
- ❺ التصفية على مستوى المجموعة باستخدام filter
2. أليس تحسب مبيعات مقهى القهوة حسب الفئة
(1) نقطة الضعف: الحلقات اليدوية مُتعبة
تريد أليس حساب المبيعات حسب فئة المشروبات. كتابة الحلقات يدوياً:
import pandas as pd
df = pd.DataFrame({
'drink': ['Latte', 'Americano', 'Mocha', 'Latte', 'Espresso',
'Americano', 'Latte', 'Mocha', 'Espresso', 'Latte'],
'category': ['Hot', 'Hot', 'Hot', 'Hot', 'Hot',
'Iced', 'Iced', 'Iced', 'Iced', 'Iced'],
'sales': [320, 280, 350, 310, 150, 200, 180, 160, 90, 120],
'quantity': [64, 56, 50, 62, 30, 40, 36, 22, 18, 24]
})
# Manual loop — tedious and error-prone
for cat in df['category'].unique():
subset = df[df['category'] == cat]
print(f"{cat}: sales={subset['sales'].sum()}, qty={subset['quantity'].sum()}")
> **الخرج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas لديك.
(2) الحل: سطر واحد باستخدام groupby
▶ مثال
> **الخرج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas لديك.
: أساسيات groupby (الصعوبة ⭐)
import pandas as pd
df = pd.DataFrame({
'drink': ['Latte', 'Americano', 'Mocha', 'Latte', 'Espresso',
'Americano', 'Latte', 'Mocha', 'Espresso', 'Latte'],
'category': ['Hot', 'Hot', 'Hot', 'Hot', 'Hot',
'Iced', 'Iced', 'Iced', 'Iced', 'Iced'],
'sales': [320, 280, 350, 310, 150, 200, 180, 160, 90, 120],
'quantity': [64, 56, 50, 62, 30, 40, 36, 22, 18, 24]
})
# One line replaces the entire loop!
result = df.groupby('category')['sales'].sum()
print(result)
# category
# Hot 1410
# Iced 750
> **الخرج:** قم بتشغيله في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعليه قليلاً حسب إصدار pandas لديك.
3. مبدأ التقسيم-التطبيق-الدمج
(1) مخطط Mermaid لعملية التجميع
graph TB
subgraph Split["① التقسيم — التقسيم حسب الفئة"]
S1["ساخن: لاتيه 320<br>أمريكانو 280<br>موكا 350<br>لاتيه 310<br>إسبريسو 150"]
S2["بارد: أمريكانو 200<br>لاتيه 180<br>موكا 160<br>إسبريسو 90<br>لاتيه 120"]
end
subgraph Apply["② التطبيق — تلخيص كل مجموعة"]
A1["ساخن → 320+280+350<br>+310+150 = 1410"]
A2["بارد → 200+180+160<br>+90+120 = 750"]
end
subgraph Combine["③ الدمج — دمج النتائج"]
C1["category | sales<br>Hot | 1410<br>Iced | 750"]
end
Split --> Apply --> Combine
> **الخرج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتاً مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. القيم الفعلية قد تختلف قليلاً اعتماداً على إصدار pandas الخاص بك.
(2) كائن GroupBy تابع للتقدير المتأخر
▶ مثال
> **الخرج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتاً مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. القيم الفعلية قد تختلف قليلاً اعتماداً على إصدار pandas الخاص بك.
: التقدير المتأخر لـ GroupBy (الصعوبة ⭐)
import pandas as pd
df = pd.DataFrame({
'category': ['Hot', 'Hot', 'Iced', 'Iced'],
'sales': [320, 280, 200, 180]
})
# groupby تُرجع كائن GroupBy — لا يوجد حساب حتى الآن
grouped = df.groupby('category')
print(type(grouped)) # <class 'pandas.core.groupby.DataFrameGroupBy'>
# الحساب يحدث عندما تستدعي عملية تجميع
print(grouped['sales'].sum())
# تفحص المجموعات
print(grouped.groups) # {'Hot': [0, 1], 'Iced': [2, 3]}
print(grouped.ngroups) # 2
# التكرار عبر المجموعات (نادراً ما يكون ضرورياً)
for name, group in grouped:
print(f"Group: {name}")
print(group)
> **الخرج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتاً مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. القيم الفعلية قد تختلف قليلاً اعتماداً على إصدار pandas الخاص بك.
4. دوال التجميع الشائعة
(1) التجميعات المدمجة
▶ مثال
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي مسبقًا على pandas مثبّتة. يرجى تثبيتها محليًا (`pip install pandas`) والمتابعة. القيم الفعلية قد تختلف قليًّا اعتمادًا على إصدار pandas الخاص بك.
: دوال التجميع المدمجة (الصعوبة ⭐⭐)
import pandas as pd
df = pd.DataFrame({
'category': ['Electronics', 'Electronics', 'Clothing', 'Clothing', 'Home', 'Home'],
'product': ['Laptop', 'Phone', 'Shirt', 'Pants', 'Lamp', 'Chair'],
'price': [999, 699, 45, 65, 30, 120],
'stock': [50, 120, 200, 180, 300, 80],
'rating': [4.7, 4.5, 4.2, 4.0, 3.8, 4.3]
})
# تجميع واحد لكل عمود
print(df.groupby('category')['price'].mean())
# Electronics 849.0
# Clothing 55.0
# Home 75.0
# أعمدة متعددة، نفس التجميع
print(df.groupby('category')[['price', 'stock']].sum())
# طرق التجميع الشائعة:
# .sum() .mean() .median() .min() .max()
# .count() .size() .std() .var() .first() .last()
# .nunique() .idxmax() .idxmin()
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي مسبقًا على pandas مثبّتة. يرجى تثبيتها محليًا (`pip install pandas`) والمتابعة. القيم الفعلية قد تختلف قليًّا اعتمادًا على إصدار pandas الخاص بك.
(2) size مقابل count
| الطريقة | ما تُحسب | معالجة NaN |
|---|---|---|
| size | عدد الصفوف لكل مجموعة (تتضمن NaN) | تتضمن NaN |
| count | عدد القيم غير NaN لكل مجموعة | تستثني NaN |
▶ مثال
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي مسبقًا على pandas مثبّتة. يرجى تثبيتها محليًا (`pip install pandas`) والمتابعة. القيم الفعلية قد تختلف قليًّا اعتمادًا على إصدار pandas الخاص بك.
: size مقابل count (الصعوبة ⭐)
import pandas as pd
import numpy as np
df = pd.DataFrame({
'category': ['A', 'A', 'B', 'B', 'A'],
'value': [1, np.nan, 3, 4, 5]
})
print(df.groupby('category').size())
# category
# A 3 ← 3 صفوف (بما في ذلك صف NaN)
# B 2
print(df.groupby('category').count())
# value
# category
# A 2 ← قيمتان غير NaN
# B 2
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي مسبقًا على pandas مثبّتة. يرجى تثبيتها محليًا (`pip install pandas`) والمتابعة. القيم الفعلية قد تختلف قليًّا اعتمادًا على إصدار pandas الخاص بك.
5. تجميعات متعددة باستخدام agg
(1) دوال تجميع متعددة
▶ مثال
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) ومتابعة الشرح. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
: تجميعات متعددة باستخدام agg (الصعوبة ⭐⭐)
import pandas as pd
df = pd.DataFrame({
'category': ['Electronics', 'Electronics', 'Clothing', 'Clothing', 'Home', 'Home'],
'product': ['Laptop', 'Phone', 'Shirt', 'Pants', 'Lamp', 'Chair'],
'price': [999, 699, 45, 65, 30, 120],
'stock': [50, 120, 200, 180, 300, 80],
'rating': [4.7, 4.5, 4.2, 4.0, 3.8, 4.3]
})
# Multiple aggregations on one column
print(df.groupby('category')['price'].agg(['mean', 'min', 'max']))
# mean min max
# category
# Clothing 55.0 45 65
# Electronics 849.0 699 999
# Home 75.0 30 120
# Different aggregations per column
print(df.groupby('category').agg({
'price': ['mean', 'max'],
'stock': 'sum',
'rating': 'mean'
}))
# Named aggregations (cleaner column names)
result = df.groupby('category').agg(
avg_price=('price', 'mean'),
max_price=('price', 'max'),
total_stock=('stock', 'sum'),
avg_rating=('rating', 'mean')
)
print(result)
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) ومتابعة الشرح. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
(2) دوال تجميع مخصصة
▶ مثال
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) ومتابعة الشرح. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
: تجميع مخصص (الصعوبة ⭐⭐⭐)
import pandas as pd
df = pd.DataFrame({
'category': ['A', 'A', 'A', 'B', 'B', 'B'],
'value': [10, 20, 30, 100, 200, 300]
})
# Custom function: range (max - min)
def value_range(series):
return series.max() - series.min()
result = df.groupby('category')['value'].agg(['mean', value_range])
print(result)
# mean value_range
# category
# A 20.0 20
# B 200.0 200
# Lambda in agg (less readable but concise)
result2 = df.groupby('category')['value'].agg([
('mean', 'mean'),
('range', lambda x: x.max() - x.min()),
('cv', lambda x: x.std() / x.mean()) # coefficient of variation
])
print(result2)
> **الناتج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتة مسبقاً. يرجى تثبيتها محلياً (`pip install pandas`) ومتابعة الشرح. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
6. التحويل داخل المجموعة باستخدام transform
(1) transform يحافظ على الشكل الأصلي
▶ مثال
> **الخرج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
: التوحيد القياسي داخل المجموعة باستخدام transform (الصعوبة ⭐⭐)
import pandas as pd
df = pd.DataFrame({
'student': ['Alice', 'Alice', 'Bob', 'Bob', 'Charlie', 'Charlie'],
'subject': ['Math', 'English', 'Math', 'English', 'Math', 'English'],
'score': [85, 90, 92, 88, 78, 82]
})
# تطبيع Z-score لكل طالب
df['z_score'] = df.groupby('student')['score'].transform(
lambda x: (x - x.mean()) / x.std()
)
print(df)
# ملء القيم المفقودة بمتوسط المجموعة (بدلاً من المتوسط العام)
df2 = pd.DataFrame({
'category': ['A', 'A', 'A', 'B', 'B'],
'value': [10, 20, None, 100, None]
})
df2['value_filled'] = df2.groupby('category')['value'].transform(
lambda x: x.fillna(x.mean())
)
print(df2)
# الترتيب داخل المجموعة
df['rank'] = df.groupby('student')['score'].transform('rank', method='min')
print(df[['student', 'subject', 'score', 'rank']])
> **الخرج:** قم بالتشغيل في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً. يرجى تثبيته محليًا (`pip install pandas`) والاتباع. القيم الفعلية قد تختلف قليلاً حسب إصدار pandas لديك.
(2) مقارنة transform مقابل agg
| الميزة | agg | transform |
|---|---|---|
| شكل القيمة المُعادة | صف واحد لكل مجموعة | نفس طول DataFrame الأصلي |
| حالة الاستخدام | تقارير ملخصة | إعادة تعبئة الجدول الأصلي |
| العمليات النموذجية | sum/mean/count | التوحيد القياسي/الملء/الترتيب |
| البث التلقائي | ❌ | ✅ يبث تلقائيًا إلى الصفوف الأصلية |
7. التصفية على مستوى المجموعة باستخدام filter
(1) الاحتفاظ بالمجموعات أو إسقاطها بناءً على شرط
▶ مثال
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). لا يتوفر خادم Pandas بشكل مسبق. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعليّة قليلاً حسب إصدار الـ pandas الخاص بك.
: تصفية المجموعات باستخدام filter (الصعوبة ⭐⭐)
import pandas as pd
df = pd.DataFrame({
'category': ['Electronics', 'Electronics', 'Electronics',
'Books', 'Books',
'Clothing', 'Clothing', 'Clothing', 'Clothing'],
'product': ['Laptop', 'Phone', 'Tablet', 'Novel', 'Textbook',
'Shirt', 'Pants', 'Jacket', 'Socks'],
'sales': [5000, 3000, 2000, 200, 300, 800, 600, 400, 100]
})
# Keep only groups where total sales > 1000
big_categories = df.groupby('category').filter(lambda x: x['sales'].sum() > 1000)
print(big_categories)
# Electronics and Clothing kept; Books dropped (200+300=500 < 1000)
# Keep groups with at least 3 items
large_groups = df.groupby('category').filter(lambda x: len(x) >= 3)
print(large_groups['category'].unique()) # ['Electronics', 'Clothing']
# Keep groups where any product has sales > 4000
has_top_seller = df.groupby('category').filter(lambda x: x['sales'].max() > 4000)
print(has_top_seller['category'].unique()) # ['Electronics']
> **الخرج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). لا يتوفر خادم Pandas بشكل مسبق. يرجى تثبيته محليًا (`pip install pandas`) واتباع الخطوات. قد تختلف القيم الفعليّة قليلاً حسب إصدار الـ pandas الخاص بك.
8. التجميع متعدد الأعمدة و as_index
(1) التجميع بعدة أعمدة
▶ مثال
> **Output:** Run in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed. Please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
: تجميع البيانات عبر عدة أعمدة (الصعوبة ⭐⭐)
import pandas as pd
df = pd.DataFrame({
'region': ['North', 'North', 'North', 'South', 'South', 'South'],
'category': ['Electronics', 'Clothing', 'Electronics',
'Electronics', 'Clothing', 'Clothing'],
'product': ['Laptop', 'Shirt', 'Phone', 'Tablet', 'Pants', 'Jacket'],
'sales': [5000, 800, 3000, 2000, 600, 400]
})
# التجميع بعدة أعمدة
result = df.groupby(['region', 'category'])['sales'].sum()
print(result)
# region category
# North Clothing 800
# Electronics 8000
# South Clothing 1000
# Electronics 2000
# as_index=False → يحافظ على أعمدة التجميع كأعمدة عادية
result2 = df.groupby(['region', 'category'], as_index=False)['sales'].sum()
print(result2)
# region category sales
# 0 North Clothing 800
# 1 North Electronics 8000
# 2 South Clothing 1000
# 3 South Electronics 2000
# sort=False → الحفاظ على الترتيب الأصلي لأول ظهور
result3 = df.groupby(['region', 'category'], sort=False)['sales'].sum()
> **Output:** Run in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed. Please install it locally (`pip install pandas`) and follow along. Actual values may vary slightly depending on your pandas version.
9. مثال كامل: تحليل متعدد الأبعاد للمجموعات للتجارة الإلكترونية
▶ مثال
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). لا يحتوي خادم Pandas على pandas مثبته مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. قد تتغير القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.
: تحليل groupby متعدد الأبعاد (الصعوبة ⭐⭐⭐)
import pandas as pd
import numpy as np
# ============================================
# مثال شامل: تحليل groupby متعدد الأبعاد
# للتجارة الإلكترونية باستخدام agg/transform/filter
# ============================================
# 1. إنشاء بيانات المبيعات
np.random.seed(42)
df = pd.DataFrame({
'region': np.random.choice(['North', 'South', 'East', 'West'], 100),
'category': np.random.choice(['Electronics', 'Clothing', 'Home', 'Sports'], 100),
'product': [f'Item_{i:03d}' for i in range(100)],
'sales': np.round(np.random.uniform(50, 2000, 100), 2),
'quantity': np.random.randint(1, 50, 100),
'discount': np.random.choice([0, 0.1, 0.2, 0.3], 100)
})
# 2. agg: ملخص متعدد المقاييس لكل فئة
summary = df.groupby('category').agg(
total_sales=('sales', 'sum'),
avg_sales=('sales', 'mean'),
max_sales=('sales', 'max'),
order_count=('sales', 'count'),
avg_quantity=('quantity', 'mean')
).round(2)
print("=== ملخص الفئات ===")
print(summary)
# 3. تجميع عمودين
region_cat = df.groupby(['region', 'category'], as_index=False).agg(
total_sales=('sales', 'sum'),
avg_discount=('discount', 'mean')
).round(3)
print("\n=== المنطقة × الفئة ===")
print(region_cat.head(8))
# 4. transform: ترتيب داخل المجموعة
df['sales_rank_in_region'] = df.groupby('region')['sales'].transform(
'rank', method='min', ascending=False
)
df['sales_pct_in_category'] = df.groupby('category')['sales'].transform(
lambda x: (x / x.sum() * 100).round(1)
)
print("\n=== أفضل 3 في الشمال ===")
print(df[df['region'] == 'North'].nsmallest(3, 'sales_rank_in_region')
[['product', 'sales', 'sales_rank_in_region']])
# 5. filter: الاحتفاظ بالفئات التي تحتوي على أكثر من 20 طلبًا
big_cats = df.groupby('category').filter(lambda x: len(x) > 20)
print(f"\n=== الفئات الكبيرة ===")
print(big_cats['category'].value_counts())
> **الإخراج:** قم بالتشغيل في بيئة بايثون محلية (pandas 2.x). لا يحتوي خادم Pandas على pandas مثبته مسبقاً. يرجى تثبيته محلياً (`pip install pandas`) واتباع الخطوات. قد تتغير القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.
❓ أسئلة شائعة
groupby؟groupby كائن GroupBy (كسول) - لا يتم أي حساب فوريًا. تُنفّذ عملية التقسيم-التطبيق-الدمج فقط عند استدعاء دالة تجميع (مثل sum/mean/agg، إلخ). يتيح هذا التصميم الكسل ربط عمليات متعددة معًا دون متغيرات وسيطة.agg و apply؟agg تُطبّق دوال التجميع على كل عمود وتُعيد صفًا واحدًا لكل مجموعة. apply تُطبّق دالة تعسفية على كل مجموعة وتُعيد نتائج أكثر مرونة (يمكنها إرجاع DataFrame). استخدم agg للتجميعات البسيطة (أسرع وأكثر وضوحًا)؛ واستخدم apply للحسابات المعقدة داخل المجموعة. تدعم agg أيضًا التجميع المسماة (name=(col, func)) لأسماء أعمدة أنظف.transform تحتفظ بالشكل؟transform نتيجة بنفس طول DataFrame الأصلي، حيث تُبث نتيجة كل مجموعة مرة أخرى إلى الصفوف الأصليه. حالات الاستخدام النمطية: التقييس داخل المجموعة (Z-score)، وملء القيم المفقودة بمتوسط المجموعة، والترتيب داخل المجموعة. يظهر خطأ إذا لم يتطابق طول النتيجة مع حجم المجموعة.filter يزيل الصفوف أم المجموعات؟filter يزيل المجموعات بأكملها — إذا لم يلبي النتاج التجميعي لمجموعة ما الشرط، تُحذف جميع صفوف تلك المجموعة. لا يقوم بتصفية صفوف فردية داخل مجموعة! يختلف هذا عن الفهرسة المنطقية (Boolean indexing): الفهرسة المنطقية تُصفّي حسب شروط على مستوى الصف، بينما يعمل filter على شروط على مستوى المجموعة.as_index=False؟groupby أعمدة التجميع إلى الفهرس (Index) (وليس أعمدة عادية). as_index=False يُبقي أعمدة التجميع كأعمدة عادية، مما يُنتج DataFrame نظيفًا بدلًا من Series متعدد الفهرسة (MultiIndex). عندما تحتاج إلى العمل على أعمدة التجميع لاحقًا (مثلًا في عملية دمج)، يكون as_index=False أكثر ملاءمة.groupby متعددة الأعمدة؟result.loc[('North', 'Electronics')] لمجموعة محددة، أو استخدم as_index=False لتجنب الفهرس الهرمي تمامًا. يمكن أيضًا لـ reset_index() تسطيح الفهرس الهرمي إلى أعمدة عادية.groupby + sort يُبطئان الأداء؟sort=True (الافتراضي) يُرتّب مفاتيح التجميع، مما يُضيف حمولة صغيرة. بالنسبة لـ DataFrame كبيرة ذات مفاتيح تجميع عالية التفرّد، يمكن لـ sort=False تسريع الأداء. ومع ذلك، تكون النتائج المُرتّبة أكثر سهولة للقراءة. التوصية: استخدم sort=True لمجموعات البيانات الصغيرة (قابلية القراءة أولاً)، و sort=False لمجموعات البيانات الكبيرة جدًا (الأداء أولاً).📖 ملخص
- جوهر عملية groupby هو التقسيم-التطبيق-الدمج: التقسيم، الحساب، الدمج
- كائن GroupBy يستخدم التقييم الكسول — الحساب يحدث فقط عند استدعاء دالة التجميع
- عمليات التجميع المدمجة: sum/mean/count/size/min/max/std/nunique، إلخ.
- agg يدعم عمليات تجميع متعددة وعمليات تجميع مختلفة لكل عمود؛ صياغة التجميع المسماة هي الأنظف
- transform يُعيد نتيجة بنفس الطول، مثالي للتعميد/الملء/الترتيب
- filter يُحدد بناءً على شروط على مستوى المجموعة، مع الاحتفاظ بمجموعات كاملة أو استبعادها
- التجميع بأعمدة متعددة يُنشئ MultiIndex؛ استخدم as_index=False لتجنب الفهرسة متعددة المستويات
📝 تمارين
- أساسي (الصعوبة ⭐): أنشئ إطار بيانات مبيعات (منطقة/فئة/مبيعات). استخدم groupby + sum/mean/count لثلاث عمليات تجميع مختلفة وقارن النتائج.
- متوسط (الصعوبة ⭐⭐): أنشئ جدول درجات الطلاب. استخدم agg لحساب المتوسط/الأعلى/الأدنى لكل مادة، واستخدم transform لحساب الدرجات المعيارية z-score لكل طالب.
- تحدي (الصعوبة ⭐⭐⭐): قم بمحاكاة 50 صفًا لطلبات التجارة الإلكترونية (منطقة/فئة/مبيعات/كمية/خصم). أكمل خط المعالجة التالي: agg ملخص متعدد المقاييس → تجميع متعدد الأعمدة (منطقة+فئة) → transform ترتيب داخل المجموعة → تصفية للاحتفاظ بالمجموعات الكبيرة → إنتاج تقرير شامل.