دليل شامل لتحسين استخدام الذاكرة في Pandas، يغطي أنواع البيانات والتقطيع والمتغيرات الفئوية والتقنيات الفعالة للتعامل مع مجموعات البيانات الكبيرة.
تحسين أداء Pandas: إتقان تقليل استخدام الذاكرة
Pandas هي مكتبة Python قوية لتحليل البيانات، توفر هياكل بيانات مرنة وأدوات تحليل البيانات. ومع ذلك، عند العمل مع مجموعات بيانات كبيرة، يمكن أن يصبح استخدام الذاكرة عنق زجاجة كبير، مما يؤثر على الأداء وحتى يتسبب في تعطل برامجك. يستكشف هذا الدليل الشامل تقنيات مختلفة لتحسين استخدام الذاكرة في Pandas، مما يسمح لك بالتعامل مع مجموعات بيانات أكبر بكفاءة وفعالية أكبر.
فهم استخدام الذاكرة في Pandas
قبل الغوص في تقنيات التحسين، من الضروري فهم كيف تخزن Pandas البيانات في الذاكرة. تستخدم Pandas في المقام الأول صفائف NumPy لتخزين البيانات داخل DataFrames و Series. يؤثر نوع البيانات لكل عمود بشكل كبير على حجم الذاكرة. على سبيل المثال، سيستهلك عمود `int64` ضعف ذاكرة عمود `int32`.
يمكنك التحقق من استخدام الذاكرة لـ DataFrame باستخدام طريقة .memory_usage():
import pandas as pd
data = {
'col1': [1, 2, 3, 4, 5],
'col2': ['A', 'B', 'C', 'D', 'E'],
'col3': [1.1, 2.2, 3.3, 4.4, 5.5]
}
df = pd.DataFrame(data)
memory_usage = df.memory_usage(deep=True)
print(memory_usage)
تعتبر الوسيطة deep=True ضرورية لحساب استخدام الذاكرة لأعمدة الكائنات (السلسلة) بدقة.
تقنيات لتقليل استخدام الذاكرة
1. تحديد أنواع البيانات الصحيحة
يعد اختيار نوع البيانات المناسب لكل عمود هو الخطوة الأساسية في تقليل استخدام الذاكرة. تستنتج Pandas أنواع البيانات تلقائيًا، لكنها غالبًا ما تعود إلى أنواع أكثر استهلاكًا للذاكرة من اللازم. على سبيل المثال، قد يتم تعيين نوع `int64` لعمود يحتوي على أعداد صحيحة بين 0 و 100، على الرغم من أن `int8` أو `uint8` ستكون كافية.
مثال: تقليل الأنواع الرقمية
يمكنك تقليل الأنواع الرقمية إلى تمثيلات أصغر باستخدام الدالة pd.to_numeric() مع المعامل downcast:
def reduce_mem_usage(df):
"""Iterate through all the columns of a dataframe and modify the data type
to reduce memory usage.
"""
start_mem = df.memory_usage().sum() / 1024**2
print('Memory usage of dataframe is {:.2f} MB'.format(start_mem))
for col in df.columns:
if df[col].dtype == 'object':
continue # Skip strings, handle them separately
col_type = df[col].dtype
if col_type in ['int64','int32','int16']:
c_min = df[col].min()
c_max = df[col].max()
if c_min > np.iinfo(np.int8).min and c_max < np.iinfo(np.int8).max:
df[col] = df[col].astype(np.int8)
elif c_min > np.iinfo(np.int16).min and c_max < np.iinfo(np.int16).max:
df[col] = df[col].astype(np.int16)
elif c_min > np.iinfo(np.int32).min and c_max < np.iinfo(np.int32).max:
df[col] = df[col].astype(np.int32)
else:
df[col] = df[col].astype(np.int64)
elif col_type in ['float64','float32']:
c_min = df[col].min()
c_max = df[col].max()
if c_min > np.finfo(np.float16).min and c_max < np.finfo(np.float16).max:
df[col] = df[col].astype(np.float16)
elif c_min > np.finfo(np.float32).min and c_max < np.finfo(np.float32).max:
df[col] = df[col].astype(np.float32)
else:
df[col] = df[col].astype(np.float64)
end_mem = df.memory_usage().sum() / 1024**2
print('Memory usage after optimization is: {:.2f} MB'.format(end_mem))
print('Decreased by {:.1f}%'.format(100 * (start_mem - end_mem) / start_mem))
return df
مثال: تحويل السلاسل إلى أنواع فئوية
إذا كان العمود يحتوي على عدد محدود من قيم السلسلة الفريدة، فإن تحويله إلى نوع فئوي يمكن أن يقلل بشكل كبير من استخدام الذاكرة. تخزن الأنواع الفئوية القيم الفريدة مرة واحدة فقط وتمثل كل عنصر في العمود كرمز عدد صحيح يشير إلى القيم الفريدة.
df['col2'] = df['col2'].astype('category')
ضع في اعتبارك مجموعة بيانات لمعاملات العملاء لمنصة تجارة إلكترونية عالمية. قد يحتوي عمود "الدولة" على بضع مئات فقط من أسماء البلدان الفريدة، بينما تحتوي مجموعة البيانات على ملايين المعاملات. سيؤدي تحويل عمود "الدولة" إلى نوع فئوي إلى تقليل استهلاك الذاكرة بشكل كبير.
2. التقطيع والتكرار
عند التعامل مع مجموعات بيانات كبيرة جدًا لا يمكن أن تتناسب مع الذاكرة، يمكنك معالجة البيانات في أجزاء باستخدام المعامل chunksize في pd.read_csv() أو pd.read_excel(). يتيح لك ذلك تحميل البيانات ومعالجتها في أجزاء أصغر يمكن التحكم فيها.
for chunk in pd.read_csv('large_dataset.csv', chunksize=100000):
# Process the chunk (e.g., perform calculations, filtering, aggregation)
print(f"Processing chunk with {len(chunk)} rows")
# Optionally, append results to a file or database.
مثال: معالجة ملفات السجل الكبيرة
تخيل معالجة ملف سجل ضخم من بنية تحتية لشبكة عالمية. ملف السجل كبير جدًا بحيث لا يمكن احتواؤه في الذاكرة. باستخدام التقطيع، يمكنك التكرار من خلال ملف السجل، وتحليل كل جزء بحثًا عن أحداث أو أنماط معينة، وتجميع النتائج دون تجاوز حدود الذاكرة.
3. تحديد الأعمدة الضرورية فقط
غالبًا ما تحتوي مجموعات البيانات على أعمدة غير ذات صلة بتحليلك. يمكن أن يؤدي تحميل الأعمدة الضرورية فقط إلى تقليل استخدام الذاكرة بشكل كبير. يمكنك تحديد الأعمدة المطلوبة باستخدام المعامل usecols في pd.read_csv().
df = pd.read_csv('large_dataset.csv', usecols=['col1', 'col2', 'col3'])
مثال: تحليل بيانات المبيعات
إذا كنت تقوم بتحليل بيانات المبيعات لتحديد المنتجات الأفضل أداءً، فقد تحتاج فقط إلى أعمدة "معرف المنتج" و"كمية المبيعات" و"إيرادات المبيعات". سيؤدي تحميل هذه الأعمدة فقط إلى تقليل استهلاك الذاكرة مقارنة بتحميل مجموعة البيانات بأكملها، والتي قد تتضمن التركيبة السكانية للعملاء وعناوين الشحن ومعلومات أخرى غير ذات صلة.
4. استخدام هياكل البيانات المتفرقة
إذا كان DataFrame الخاص بك يحتوي على العديد من القيم المفقودة (NaNs) أو الأصفار، فيمكنك استخدام هياكل البيانات المتفرقة لتمثيل البيانات بكفاءة أكبر. تقوم DataFrames المتفرقة بتخزين القيم غير المفقودة أو غير الصفرية فقط، مما يقلل بشكل كبير من استخدام الذاكرة عند التعامل مع البيانات المتفرقة.
sparse_series = df['col1'].astype('Sparse[float]')
sparse_df = sparse_series.to_frame()
مثال: تحليل تقييمات العملاء
ضع في اعتبارك مجموعة بيانات لتقييمات العملاء لعدد كبير من المنتجات. سيقوم معظم العملاء بتقييم مجموعة فرعية صغيرة فقط من المنتجات، مما يؤدي إلى إنشاء مصفوفة تقييمات متفرقة. سيؤدي استخدام DataFrame متفرق لتخزين هذه البيانات إلى تقليل استهلاك الذاكرة بشكل كبير مقارنة بـ DataFrame كثيف.
5. تجنب نسخ البيانات
يمكن أن تؤدي عمليات Pandas أحيانًا إلى إنشاء نسخ من DataFrames، مما يؤدي إلى زيادة استخدام الذاكرة. يمكن أن يساعد تعديل DataFrame في مكانه (عند الإمكان) في تجنب النسخ غير الضروري.
على سبيل المثال، بدلاً من:
df = df[df['col1'] > 10]
ضع في اعتبارك استخدام:
df.drop(df[df['col1'] <= 10].index, inplace=True)
تقوم الوسيطة `inplace=True` بتعديل DataFrame مباشرة دون إنشاء نسخة.
6. تحسين تخزين السلاسل
يمكن أن تستهلك أعمدة السلسلة قدرًا كبيرًا من الذاكرة، خاصةً إذا كانت تحتوي على سلاسل طويلة أو العديد من القيم الفريدة. يعد تحويل السلاسل إلى أنواع فئوية، كما ذكرنا سابقًا، إحدى التقنيات الفعالة. هناك طريقة أخرى تتمثل في استخدام تمثيلات سلسلة أصغر إذا أمكن.
مثال: تقليل طول السلسلة
إذا كان العمود يحتوي على معرفات مخزنة كسلاسل ولكن يمكن تمثيلها كأعداد صحيحة، فإن تحويلها إلى أعداد صحيحة يمكن أن يوفر الذاكرة. على سبيل المثال، يمكن تعيين معرفات المنتج المخزنة حاليًا كسلاسل مثل "PROD-1234" إلى معرفات عدد صحيح.
7. استخدام Dask لمجموعات البيانات الأكبر من الذاكرة
بالنسبة لمجموعات البيانات الكبيرة حقًا بحيث لا يمكن احتواؤها في الذاكرة، حتى مع التقطيع، ففكر في استخدام Dask. Dask هي مكتبة حوسبة متوازية تتكامل جيدًا مع Pandas و NumPy. يسمح لك بالعمل مع مجموعات بيانات أكبر من الذاكرة عن طريق تقسيمها إلى أجزاء أصغر ومعالجتها بالتوازي عبر نوى متعددة أو حتى أجهزة متعددة.
import dask.dataframe as dd
ddf = dd.read_csv('large_dataset.csv')
# Perform operations on the Dask DataFrame (e.g., filtering, aggregation)
result = ddf[ddf['col1'] > 10].groupby('col2').mean().compute()
تقوم الطريقة compute() بتشغيل الحساب الفعلي وإرجاع Pandas DataFrame يحتوي على النتائج.
أفضل الممارسات والاعتبارات
- تحليل التعليمات البرمجية الخاصة بك: استخدم أدوات التحليل لتحديد اختناقات الذاكرة وركز جهود التحسين على المجالات الأكثر تأثيرًا.
- اختبر تقنيات مختلفة: تعتمد تقنية تقليل الذاكرة المثالية على الخصائص المحددة لمجموعة البيانات الخاصة بك. جرب أساليب مختلفة للعثور على أفضل حل لحالة الاستخدام الخاصة بك.
- مراقبة استخدام الذاكرة: تتبع استخدام الذاكرة أثناء معالجة البيانات للتأكد من أن عمليات التحسين الخاصة بك فعالة ومنع أخطاء نفاد الذاكرة.
- فهم بياناتك: يعد الفهم العميق لبياناتك أمرًا بالغ الأهمية لاختيار أنواع البيانات وتقنيات التحسين الأنسب.
- ضع في اعتبارك المفاضلات: قد تؤدي بعض تقنيات تحسين الذاكرة إلى زيادة طفيفة في أداء النظام. قم بوزن فوائد تقليل استخدام الذاكرة مقابل أي تأثير محتمل على الأداء.
- توثيق عمليات التحسين الخاصة بك: قم بتوثيق تقنيات تحسين الذاكرة التي قمت بتنفيذها بوضوح للتأكد من أن التعليمات البرمجية الخاصة بك قابلة للصيانة وقابلة للفهم من قبل الآخرين.
استنتاج
يعد تحسين استخدام الذاكرة في Pandas أمرًا ضروريًا للعمل مع مجموعات البيانات الكبيرة بكفاءة وفعالية. من خلال فهم كيفية تخزين Pandas للبيانات، وتحديد أنواع البيانات الصحيحة، واستخدام التقطيع، وتوظيف تقنيات التحسين الأخرى، يمكنك تقليل استهلاك الذاكرة بشكل كبير وتحسين أداء مهام سير عمل تحليل البيانات. قدم هذا الدليل نظرة عامة شاملة على التقنيات والممارسات الأساسية لإتقان تقليل استخدام الذاكرة في Pandas. تذكر تحليل التعليمات البرمجية الخاصة بك، واختبار تقنيات مختلفة، ومراقبة استخدام الذاكرة لتحقيق أفضل النتائج لحالة الاستخدام الخاصة بك. من خلال تطبيق هذه المبادئ، يمكنك إطلاق الإمكانات الكاملة لـ Pandas ومعالجة حتى أصعب تحديات تحليل البيانات.
من خلال إتقان هذه التقنيات، يمكن لعلماء البيانات والمحللين في جميع أنحاء العالم التعامل مع مجموعات بيانات أكبر وتحسين سرعات المعالجة واكتساب رؤى أعمق من بياناتهم. وهذا يساهم في إجراء أبحاث أكثر كفاءة واتخاذ قرارات تجارية مستنيرة بشكل أفضل وفي النهاية عالم أكثر اعتمادًا على البيانات.