Pandas: أنواع البيانات

آخر تحديث: 2026-08-26

يحدد نوع البيانات (dtype) كيفية تخزين Pandas لبياناتك والتعامل معها. اختر النوع الصحيح من dtype وستتمكن من تشغيل كودك بسرعة أكبر 10 مرات مع استخدام ذاكرة أقل بنسبة 80%؛ أما اختيار النوع الخطأ فيواجهك فقدان الدقة، وأخطاء في العمليات، وانفجارات في استهلاك الذاكرة. يأخذك هذا القسم في جولة عبر نظام dtype في Pandas، ليساعدك على فهم خصائص كل نوع وطرق التحويل بينها، بالإضافة إلى أكثر تقنيات تحسين الذاكرة عملية.

⚠️ ملاحظة: يجب تشغيل الكود أدناه في بيئة Python محلية.

1. ما ستتعلمه



2. أزمة انفجار ذاكرة بوب

(1) نقطة الألم: جدول عملاء بحجم 500 ميجابايت

حمل بوب مجموعة بيانات العملاء في DataFrame وفحص استخدام الذاكرة — 500 ميجابايت! 100 ألف صف لا ينبغي أن يشغل كل هذا المساحة:

PYTHON
import pandas as pd

# Load customer data (simulated)
df = pd.DataFrame({
    'customer_id': range(100000),
    'name': ['Customer_' + str(i) for i in range(100000)],
    'city': ['New York', 'London', 'Tokyo', 'Paris', 'Sydney'] * 20000,
    'age': [25 + i % 50 for i in range(100000)],
    'loyalty_points': [100 + i * 10 for i in range(100000)]
})

print(f"Memory before optimization: {df.memory_usage(deep=True).sum() / 1024 / 1024:.1f} MB")
# Typical output: ~18 MB (this example is small)
# Real 100K-row dataset with many string columns can reach 500+ MB
TEXT 📖 للعرض فقط
> **المخرجات:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليًلا اعتمادًا على إصدار pandas الخاص بك.

المتسبب: نوع الكائن. بشكل افتراضي، يقوم Pandas بأعمدة النصوص بتخزينها كـ كائن (مؤشرات كائنات Python)، حيث يكون كل عنصر كائن نص Python كامل — وهو عبء ضخم على الذاكرة.

(2) الحل: ضغط 10 أضعاف باستخدام النوع category

▶ مثال

TEXT 📖 للعرض فقط
> **المخرجات:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليًلا اعتمادًا على إصدار pandas الخاص بك.

: تحسين الذاكرة باستخدام category (الصعوبة ⭐⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'customer_id': range(100000),
    'name': ['Customer_' + str(i) for i in range(100000)],
    'city': ['New York', 'London', 'Tokyo', 'Paris', 'Sydney'] * 20000,
    'age': [25 + i % 50 for i in range(100000)],
    'loyalty_points': [100 + i * 10 for i in range(100000)]
})

# Check memory before optimization
mem_before = df.memory_usage(deep=True).sum() / 1024 / 1024

# Optimize: city has only 5 unique values → category
df['city'] = df['city'].astype('category')

# Optimize: age range 25-74 → int8 is enough (max 127)
df['age'] = df['age'].astype('int8')

# Optimize: loyalty_points range → int32 is enough
df['loyalty_points'] = df['loyalty_points'].astype('int32')

mem_after = df.memory_usage(deep=True).sum() / 1024 / 1024
print(f"Before: {mem_before:.1f} MB")
print(f"After:  {mem_after:.1f} MB")
print(f"Saved:  {(1 - mem_after/mem_before)*100:.0f}%")
# Before: ~18 MB
# After:  ~5 MB
# Saved:  ~72%
TEXT 📖 للعرض فقط
> **المخرجات:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليًلا اعتمادًا على إصدار pandas الخاص بك.

(3) العائد: 3 تقنيات تحسين أساسية

التقنية التأثير متى تُستخدم
كائن→category تقليل الذاكرة بنسبة 90%+ سلاسل منخفضة التعددية (القيم الفريدة < 50% من عدد الصفوف)
int64→int8/int16/int32 تقليل الذاكرة بنسبة ~75% نطاقات عددية صغيرة
float64→float32 تقليل الذاكرة بنسبة 50% متطلبات دقة منخفضة


3. نظام أنواع البيانات (dtype) في Pandas

(1) المشهد الكامل للأنواع

100%
graph TB
    DT["Pandas dtype"] --> NUM["Numeric"]
    DT --> STR["String-like"]
    DT --> DT_TYPE["Datetime"]
    DT --> BOOL["Boolean"]
    DT --> CAT["Categorical"]
    DT --> NULL["Nullable"]

    NUM --> I["int8/16/32/64"]
    NUM --> UI["uint8/16/32/64"]
    NUM --> F["float32/float64"]

    STR --> O["object (legacy)"]
    STR --> SD["StringDtype (new)"]

    DT_TYPE --> DT64["datetime64[ns]"]
    DT_TYPE --> TD64["timedelta64[ns]"]

    BOOL --> PB["bool (NumPy)"]
    BOOL --> NB["boolean (Nullable)"]

    NULL --> NI["Int8/16/32/64"]
    NULL --> NF["Float32/64"]
    NULL --> NBO["boolean"]
    NULL --> NS["string"]
TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). لا يحتوي خادم Pandas على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلاً اعتماداً على إصدار pandas لديك.

(2) نوع بيانات Pandas مقابل نوع بيانات NumPy

الميزة نوع بيانات NumPy نوع بيانات Pandas
الأنواع الرقمية int8~64 / float32~64 نفس NumPy + الأنواع القابلة للتعليق (Int64/Float64)
السلاسل النصية كائن كائن / StringDtype / سلسلة
القيم المنطقية (Boolean) bool bool / منطقي (قابل للتعليق)
القيم المفقودة np.nan (float فقط) NaN / NaT / pd.NA (تغطية كاملة)
الفئات (Categorical) لا يوجد category
الوقت datetime64 datetime64[ns] / timedelta64[ns]
الامتداد (Extension) لا يوجد ExtensionDtype (مخصص)
📌 نقطة جوهرية: الأنواع القابلة للتعليق في Pandas (بالأحرف الكبيرة: Int64 / Float64 / منطقي / سلسلة) هي ميزة تم تقديمها في الإصدار 1.0. تستخدم pd.NA لتمثيل القيم المفقودة بشكل موحد، مما حل المشكلة القديمة المتمثلة في أن "أعمدة الأعداد الصحيحة لا يمكنها احتواء NaN."



4. كائن مقابل StringDtype مقابل category

(1) مقارنة بين الثلاثة

الميزة كائن StringDtype category
التخزين الأساسي مؤشرات كائنات بايثون تخزين سلاسل نصية مخصص أكواد عددية كاملة + جدول بحث
القيم المفقودة None / np.nan pd.NA pd.NA
الذاكرة الأعلى المتوسطة الأقل (لعدد منخفض من القيم الفريدة)
الطرق النصية مُوصِل .str accessor مُوصِل .str accessor مُوصِل .str accessor
المقارنات قد تكون غير متسقة متسقة متسقة
الترتيب المعجمي (Lexicographic) المعجمي يدعم ترتيب مخصص
الأفضل لـ التوافق مع الكود القديم مُوصى به للمشاريع الجديدة الأعمدة ذات عدد منخفض من القيم الفريدة

▶ مثال

TEXT 📖 للعرض فقط
> **الخرج:** شغّل هذا في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مُثبَّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) لاتباع المثال. قد تختلف القيم الفعلية قليًًا حسب إصدار pandas الخاص بك.

: مقارنة استهلاك الذاكرة بين الأنواع الثلاثة (الصعوبة ⭐⭐)

PYTHON
import pandas as pd
import numpy as np

# 1000 صف، 5 مدن فريدة
cities = ['New York', 'London', 'Tokyo', 'Paris', 'Sydney']
data = [cities[i % 5] for i in range(1000)]

s_object = pd.Series(data, dtype='object')
s_string = pd.Series(data, dtype='string')
s_category = pd.Series(data, dtype='category')

print(f"object:   {s_object.memory_usage(deep=True) / 1024:.1f} KB")
print(f"string:   {s_string.memory_usage(deep=True) / 1024:.1f} KB")
print(f"category: {s_category.memory_usage(deep=True) / 1024:.1f} KB")
# object:   ~62 KB
# string:   ~55 KB
# category: ~5 KB  ← أصغر بـ 12 مرة!
TEXT 📖 للعرض فقط
> **الخرج:** شغّل هذا في بيئة بايثون محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مُثبَّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) لاتباع المثال. قد تختلف القيم الفعلية قليًًا حسب إصدار pandas الخاص بك.
🔥 خطأ شائع: عندما يقترب عدد القيم الفريدة من عدد الصفوف (أي تكون الكاردينالية عالية)، فإن category يستخدم فعليًا ذاكرة أكثر من object — لأنه يحتاج إلى الحفاظ على جدول تعيين كامل. القاعدة العامة: تكون category مفيدة عندما تكون القيم الفريدة أقل من 50% من عدد الصفوف.



5. طرق تحويل الأنواع

(1) astype: التحويل الصريح

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

: astype تحويل الأنواع (الصعوبة ⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'price_str': ['9.99', '19.99', '29.99'],
    'quantity_int': [1, 3, 5],
    'flag_str': ['True', 'False', 'True']
})

# من سلسلة نصية إلى عدد عشري
df['price'] = df['price_str'].astype(float)

# من عدد صحيح إلى سلسلة نصية (لأعمدة المعرّفات)
df['qty_str'] = df['quantity_int'].astype(str)

# من سلسلة نصية إلى قيمة منطقية (انتبه: 'True'/'False' كنصوص → bool)
df['flag'] = df['flag_str'].map({'True': True, 'False': False})

print(df.dtypes)
# price_str       object
# quantity_int     int64
# flag_str        object
# price          float64
# qty_str         object
# flag              bool
TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

(2) convert_dtypes: استنتاج أفضل نوع تلقائيًا

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

: convert_dtypes التحويل التلقائي (الصعوبة ⭐⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'name': ['Alice', 'Bob', 'Charlie'],
    'age': [28, 34, 25],
    'score': [85.5, 92.0, 78.3],
    'active': [True, True, False]
})

# التحويل إلى أفضل أنواع قابلة لل null
df_converted = df.convert_dtypes()
print(df_converted.dtypes)
# name      string    ← object → StringDtype
# age        Int64    ← int64 → nullable Int64
# score    Float64    ← float64 → nullable Float64
# active   boolean    ← bool → nullable boolean
TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

(3) infer_objects: استنتاج أفضل نوع لأعمدة الكائنات

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

: infer_objects الاستنتاج (الصعوبة ⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'a': [1, 2, 3],       # مخزن كـ object
    'b': ['x', 'y', 'z']  # يبقى كـ object
}, dtype='object')

print(df.dtypes)
# a    object
# b    object

df_inferred = df.infer_objects()
print(df_inferred.dtypes)
# a     int64   ← تم استنتاجه من المحتوى
# b    object   ← لا يزال object (النصوص تبقى)
TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبّتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعليّة قليلًا اعتمادًا على إصدار pandas الخاص بك.

(4) مقارنة طرق التحويل

الطريقة الغرض تلقائي/يدوي قابل للـ فارغ
astype() إجبار التحويل إلى نوع محدد يدوي ليس تلقائيًا
convert_dtypes() استنتاج أفضل نوع قابل للـ فارغ تلقائي نعم
infer_objects() استنتاج نوع أعمدة الكائنات تلقائي ليس تلقائيًا


6. أنواع Nullable: حل مشكلة القيم المفقودة في الأعداد الصحيحة

(1) لماذا تحتاج أنواع Nullable

لا يمكن لـ int64 في NumPy تخزين NaN — عندما يحتوي عمود من الأعداد الصحيحة على قيم مفقودة، يُضطر Pandas إلى ترقية العمود بالكامل إلى float64، مما يفقد النوع الأصلي.

▶ مثال

TEXT 📖 للعرض فقط
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed — install it locally (`pip install pandas`) to follow along. Actual values may vary slightly depending on your pandas version.

: Nullable مقابل الأنواع التقليدية (الصعوبة ⭐⭐)

PYTHON
import pandas as pd
import numpy as np

# Traditional: int column with NaN → forced to float
s_trad = pd.Series([1, 2, np.nan, 4])
print(s_trad)         # 1.0, 2.0, NaN, 4.0 — floats!
print(s_trad.dtype)   # float64

# Nullable: Int64 keeps integer type with <NA>
s_null = pd.Series([1, 2, pd.NA, 4], dtype='Int64')
print(s_null)         # 1, 2, <NA>, 4 — integers!
print(s_null.dtype)   # Int64

# Nullable boolean
b_null = pd.Series([True, False, pd.NA], dtype='boolean')
print(b_null)

# Nullable string
str_null = pd.Series(['Alice', pd.NA, 'Charlie'], dtype='string')
print(str_null)
TEXT 📖 للعرض فقط
> **Output:** Run this in a local Python environment (pandas 2.x). The Piston server does not have pandas pre-installed — install it locally (`pip install pandas`) to follow along. Actual values may vary slightly depending on your pandas version.

(2) لمحة عن أنواع Nullable

النوع القابل لل-فارغ المقابل التقليدي علامة القيمة المفقودة متى تُستخدم
Int8/16/32/64 int8/16/32/64 pd.NA أعمدة الأعداد الصحيحة التي تحتوي على قيم مفقودة
Float32/64 float32/64 pd.NA أعمدة الأعداد العشرية التي تحتوي على قيم مفقودة
منطقي bool pd.NA أعمدة القيم المنطقية (Boolean) التي تحتوي على قيم مفقودة
سلسلة كائن pd.NA أعمدة النصوص (تستبدل كائن)
💡 نصيحة: تستخدم أنواع Nullable رمز pd.NA لتمثيل القيم المفقودة بشكل موحد، مما يحل محل المزيج الفوضوي من np.nan / None / NaT. أثناء العمليات، يتبع pd.NA "قاعدة الانتشار" — أي عملية تتضمن pd.NA تُرجع pd.NA.



7. تحسين الذاكرة في الممارسة العملية

(1) التحقق من استخدام الذاكرة

▶ مثال

TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيل هذا في بيئة Python المحلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.

: تحليل memory_usage (الصعوبة ⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'id': range(10000),
    'city': ['New York', 'London', 'Tokyo', 'Paris', 'Sydney'] * 2000,
    'score': [85.5 + i * 0.1 for i in range(10000)],
    'status': ['Active', 'Inactive', 'Pending'] * 3333 + ['Active']
})

# استخدام الذاكرة لكل عمود (deep=True لأعمدة الكائنات)
print(df.memory_usage(deep=True))
# Index           80
# id            80000    ← int64 لـ 10 آلاف صف
# city         630000    ← كائن (ضخم!)
# score        80000    ← float64
# status       460000    ← كائن (ضخم!)

# الإجمالي
total = df.memory_usage(deep=True).sum() / 1024 / 1024
print(f"الإجمالي: {total:.1f} ميجابايت")
TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيل هذا في بيئة Python المحلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.

(2) استراتيجيات التحسين

▶ مثال

TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيل هذا في بيئة Python المحلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.

: تحسين الذاكرة من البداية للنهاية (الصعوبة ⭐⭐⭐)

PYTHON
import pandas as pd

df = pd.DataFrame({
    'id': range(10000),
    'city': ['New York', 'London', 'Tokyo', 'Paris', 'Sydney'] * 2000,
    'score': [85.5 + i * 0.1 for i in range(10000)],
    'status': ['Active', 'Inactive', 'Pending'] * 3333 + ['Active']
})

mem_before = df.memory_usage(deep=True).sum() / 1024 / 1024

# 1. أعمدة النص ذات الحد الأدنى من القيم الفريدة → فئة
df['city'] = df['city'].astype('category')
df['status'] = df['status'].astype('category')

# 2. تقليص النطاق العددي
df['id'] = pd.to_numeric(df['id'], downcast='integer')   # int64 → int16
df['score'] = pd.to_numeric(df['score'], downcast='float')  # float64 → float32

mem_after = df.memory_usage(deep=True).sum() / 1024 / 1024

print(f"قبل: {mem_before:.1f} ميجابايت")
print(f"بعد:  {mem_after:.1f} ميجابايت")
print(f"وفّر:  {(1 - mem_after/mem_before)*100:.0f}%")
print(f"\nأنواع البيانات المحسّنة:")
print(df.dtypes)
TEXT 📖 للعرض فقط
> **الخرج:** قم بتشغيل هذا في بيئة Python المحلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبتًا مسبقًا — قم بتثبيته محليًا (`pip install pandas`) للمتابعة. قد تختلف القيم الفعلية قليلاً حسب إصدار pandas الخاص بك.

(3) جدول مرجعي لتقليص النطاق

النوع الأصلي downcast='integer' downcast='float' التوفير
int64 int8/int16/int32 (يختار الأصغر تلقائيًا) 50%~75%
float64 float32 50%
uint64 uint8/uint16/uint32 50%~75%


8. مثال كامل: تحسين جدول عملاء كبير

▶ مثال

TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً — قم بتثبيته محلياً (`pip install pandas`) للمتابعة. قد تتغير القيم الفعليبة قليلاً حسب إصدار pandas الخاص بك.

: خط أنابيب تحسين كامل لجدول العملاء (الصعوبة ⭐⭐⭐)

PYTHON
import pandas as pd
import numpy as np

# ============================================
# مثال شامل: جدول العملاء
# خط أنابيب التحسين الكامل
# ============================================

# 1. إنشاء بيانات عملاء واقعية
n = 50000
df = pd.DataFrame({
    'customer_id': range(n),
    'name': [f'Customer_{i:05d}' for i in range(n)],
    'city': np.random.choice(['New York', 'London', 'Tokyo', 'Paris',
                               'Sydney', 'Berlin', 'Toronto', 'Seoul'], n),
    'age': np.random.randint(18, 80, n),
    'membership': np.random.choice(['Basic', 'Silver', 'Gold', 'Platinum'], n),
    'points': np.random.randint(0, 100000, n),
    'satisfaction': np.random.choice([1, 2, 3, 4, 5, np.nan], n, p=[0.05,0.1,0.2,0.3,0.3,0.05])
})

# 2. التحليل قبل التحسين
print("=== BEFORE Optimization ===")
print(df.dtypes)
mem_before = df.memory_usage(deep=True).sum() / 1024 / 1024
print(f"Total memory: {mem_before:.1f} MB")

# 3. التحسين
# سلاسل نصية منخفضة البطاقة → فئة
for col in ['city', 'membership']:
    df[col] = df[col].astype('category')

# تخفيض الأعداد الصحيحة
for col in ['customer_id', 'age', 'points']:
    df[col] = pd.to_numeric(df[col], downcast='integer')

# عدد عشري مع NaN → Int64 قابل للnull
df['satisfaction'] = df['satisfaction'].astype('Int8')

# 4. التحليل بعد التحسين
print("\n=== AFTER Optimization ===")
print(df.dtypes)
mem_after = df.memory_usage(deep=True).sum() / 1024 / 1024
print(f"Total memory: {mem_after:.1f} MB")
print(f"Saved: {(1 - mem_after/mem_before)*100:.0f}%")

# 5. التحقق من سلامة البيانات
print(f"\n=== Integrity Check ===")
print(f"Rows: {len(df)}")
print(f"Satisfaction with NaN: {df['satisfaction'].isna().sum()}")
print(f"Unique cities: {df['city'].nunique()}")
TEXT 📖 للعرض فقط
> **الإخراج:** قم بتشغيل هذا في بيئة Python محلية (pandas 2.x). خادم Piston لا يحتوي على pandas مثبته مسبقاً — قم بتثبيته محلياً (`pip install pandas`) للمتابعة. قد تتغير القيم الفعليبة قليلاً حسب إصدار pandas الخاص بك.

❓ أسئلة شائعة

س ما الفرق بين كائن و سلسلة؟
ج كائن هو مصفوفة من مؤشرات كائنات بايثون - كل عنصر هو كائن سلسلة نصية منفصل من بايثون مع حجم مخزن كبير للبيانات الفوقية. سلسلة (StringDtype) هو نوع سلسلة نصية مخصص تم إدخاله في Pandas 1.0+ يستخدم pd.NA للقيم المفقودة ويوفر بنيات تشغيل أكثر اتساقًا. للمشاريع الجديدة، يُفضل استخدام سلسلة بدلاً من كائن.
س ما فوائد الأنواع القابلة للقيمة الفارغة (Nullable)؟
ج تحل مشكلة قديمة مفادها أن "عمودًا من الأعداد الصحيحة مع قيم مفقودة يتحول بالقوة إلى أعداد عشرية." Int64 يمكنه استيعاب كل من الأعداد الصحيحة و pd.NA مع الحفاظ على بنيات الأعداد الصحيحة. على سبيل المثال، عمود عمر العميل مع قيم مفقودة يبقى من نوع عدد صحيح (Int8) بدلاً من أن يصبح float64.
س متى يجب استخدام category؟
ج عندما تكون القيم الفريدة في عمود أقل بكثير من عدد صفوفه (قاعدة تقريبية: القيم الفريدة < 50% من الصفوف). الحالات النموذجية: أعمدة ذا فئات محدودة مثل المدينة، الجنس، الحالة، أو المستوى. category تستبدل السلاسل النصية المتكررة برموز عددية وجدول بحث، مما يقلل الذاكرة بنسبة 90%+. لا مناسب للأعمدة ذات البطاقات العالية (مثل معرفات المستخدمين).
س ما الفرق بين convert_dtypes و astype؟
ج يتطلب astype منك تحديد النوع الهدف يدويًا (مثل astype('int64'))، بينما convert_dtypes يستنتج تلقائيًا أفضل نوع Nullable (كائن→سلسلة، int64→Int64، float64→Float64). astype أكثر دقة؛ convert_dtypes أكثر راحة.
س كيف أتحقق من استخدام الذاكرة؟
ج يُعيد df.memory_usage(deep=True) عدد البايتات لكل عمود. يحسب deep=True الذاكرة الفعلية للسلاسل النصية في أعمدة كائن (وليس فقط أحجام المؤشرات). df.info(memory_usage='deep') يُظهر أيضًا الذاكرة الإجمالية.
س هل تخفيض الدقة (downcast) آمن؟
ج نعم - يختار pd.to_numeric(downcast=...) تلقائيًا أصغر نوع يمكنه استيعاب نطاق البيانات. على سبيل المثال، الأعداد الصحيحة من 0-100 ستختار uint8 (0-255) بدون فيض. ولكن إذا أضفت لاحقًا بيانات خارج هذا النطاق، فقد يتم اقتصاصها أو ترقيتها بهدوء. من الأفضل تشغيل تخفيض الدقة كخطوة نهائية بعد اكتمال تنظيف البيانات.
س لماذا يكون memory_usage كبيرًا جدًا لأعمدة السلاسل النصية؟
ج كل عنصر في عمود كائن/سلسلة هو كائن بايثون منفصل مع أكثر من 50 بايت من البيانات الفوقية للكائن. 10,000 صف من السلاسل النصية يمكن أن تشغل 600 كيلوبايت، بينما نفس العدد من صفوف int64 يشغل فقط 80 كيلوبايت. الحل: استخدم category للبيانات منخفضة البطاقات، وفكّر في المعالجة بالقطع للبيانات عالية البطاقات.

📖 ملخص


📝 تمارين

  1. أساسي (صعوبة ⭐): قم بإنشاء DataFrame يحتوي على 3 أعمدة (سلسلة نصية/عدد صحيح/عدد عشري). تحقق من الأنواع باستخدام dtypes، ثم استخدم astype لتحويل العمود الصحيح إلى int8 والعمود العشري إلى float32. قارن التغيير في memory_usage.
  2. متوسط (صعوبة ⭐⭐): أنشئ Series عددية صحيحة تحتوي على NaN. تعامل معها بالطريقة التقليدية (التي يتم تحويلها تلقائيًا إلى float64) ومع نوع Nullable Int64، ثم قارن بين dtype وسلوك العمليات. بعد ذلك، قم بتحسين عمود سلسلة نصية يحتوي على 5 قيم فريدة باستخدام نوع category.
  3. تحدي (صعوبة ⭐⭐⭐): قم بإنشاء DataFrame محاكٍ يحتوي على 10,000 صف و 4 أعمدة (سلسلة نصية ذات بطاقة منخفضة / سلسلة نصية ذات بطاقة عالية / عدد صحيح / عدد عشري). قم بتشغيل خطوة تحسين الذاكرة الكاملة: فحص → بطاقة منخفضة → category → downcast → Nullable → تحقق. اطبع تغيير الذاكرة في كل خطوة ونسبة التوفير النهائية.

← Previous: Index System · Next: Data Selection →

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%