رغم أن DataStore متوافق إلى حدٍ كبير مع pandas، فهناك اختلافات مهمة ينبغي فهمها.
الجدول الملخّص
| Aspect | pandas | DataStore |
|---|---|---|
| التنفيذ | فوري (مباشر) | مؤجل (عند الحاجة) |
| أنواع الإرجاع | DataFrame/Series | DataStore/ColumnExpr |
| ترتيب الصفوف | محفوظ | محفوظ (تلقائيًا)؛ غير مضمون في وضع الأداء |
| inplace | مدعوم | غير مدعوم |
| الفهرس | دعم كامل | مبسّط |
| الذاكرة | جميع البيانات في الذاكرة | البيانات في المصدر |
1. التنفيذ المؤجل مقابل التنفيذ الفوري
pandas (التنفيذ الفوري)
تُنفَّذ العمليات مباشرةً:
import pandas as pd
df = pd.read_csv("data.csv") # Loads entire file NOW
result = df[df['age'] > 25] # Filters NOW
grouped = result.groupby('city')['salary'].mean() # Aggregates NOWDataStore (مؤجل)
تُؤجَّل العمليات حتى تدعو الحاجة إلى النتائج:
from chdb import datastore as pd
ds = pd.read_csv("data.csv") # Just records the source
result = ds[ds['age'] > 25] # Just records the filter
grouped = result.groupby('city')['salary'].mean() # Just records
# Execution happens here:
print(grouped) # Executes when displaying
df = grouped.to_df() # Or when converting to pandasلماذا يُعد هذا مهمًا
يُمكّن التنفيذ المؤجل مما يلي:
- تحسين الاستعلامات: تُجمَّع عمليات متعددة في استعلام SQL واحد
- استبعاد الأعمدة غير اللازمة: لا تُقرأ إلا الأعمدة المطلوبة
- تطبيق عوامل التصفية عند المصدر: تُطبَّق عوامل التصفية عند المصدر
- كفاءة الذاكرة: لا تُحمِّل بيانات لا تحتاج إليها
2. أنواع الإرجاع
pandas
df['col'] # Returns pd.Series
df[['a', 'b']] # Returns pd.DataFrame
df[df['x'] > 10] # Returns pd.DataFrame
df.groupby('x') # Returns DataFrameGroupByDataStore
ds['col'] # Returns ColumnExpr (lazy)
ds[['a', 'b']] # Returns DataStore (lazy)
ds[ds['x'] > 10] # Returns DataStore (lazy)
ds.groupby('x') # Returns LazyGroupByالتحويل إلى أنواع بيانات pandas
# Get pandas DataFrame
df = ds.to_df()
df = ds.to_pandas()
# Get pandas Series from column
series = ds['col'].to_pandas()
# Or trigger execution
print(ds) # Automatically converts for display3. محفزات التنفيذ
يُنفَّذ DataStore عندما تحتاج إلى القيم الفعلية:
| المحفّز | مثال | ملاحظات |
|---|---|---|
print() / repr() |
print(ds) |
يتطلب العرض بيانات |
len() |
len(ds) |
يتطلب معرفة عدد الصفوف |
.columns |
ds.columns |
يتطلب أسماء الأعمدة |
.dtypes |
ds.dtypes |
يتطلب معلومات الأنواع |
.shape |
ds.shape |
يتطلب الأبعاد |
.values |
ds.values |
يتطلب البيانات الفعلية |
.index |
ds.index |
يتطلب الفهرس |
to_df() |
ds.to_df() |
تحويل صريح |
| التكرار | for row in ds |
يتطلب التكرار |
equals() |
ds.equals(other) |
يتطلب المقارنة |
العمليات التي تظل مؤجلة التنفيذ
| العملية | الناتج |
|---|---|
filter() |
DataStore |
select() |
DataStore |
sort() |
DataStore |
groupby() |
LazyGroupBy |
join() |
DataStore |
ds['col'] |
ColumnExpr |
ds[['a', 'b']] |
DataStore |
ds[condition] |
DataStore |
4. ترتيب الصفوف
pandas
يُحافَظ دائمًا على ترتيب الصفوف:
df = pd.read_csv("data.csv")
print(df.head()) # Always same order as fileDataStore
يُحفَظ ترتيب الصفوف تلقائيًا في معظم العمليات:
ds = pd.read_csv("data.csv")
print(ds.head()) # Matches file order
# Filter preserves order
ds_filtered = ds[ds['age'] > 25] # Same order as pandasيتتبع DataStore تلقائيًا مواضع الصفوف الأصلية داخليًا (باستخدام rowNumberInAllBlocks()) لضمان اتساق ترتيبها مع pandas.
عندما يكون الترتيب محفوظًا
- مصادر الملفات (CSV، Parquet، JSON، إلخ)
- مصادر pandas DataFrame
- عمليات التصفية
- اختيار الأعمدة
- بعد استخدام
sort()أوsort_values()بشكل صريح - العمليات التي تحدد الترتيب (
nlargest()،nsmallest()،head()،tail())
متى قد يختلف الترتيب
- بعد عمليات التجميع
groupby()(استخدمsort_values()لضمان اتساق الترتيب) - بعد
merge()/join()مع بعض أنواع الربط - في وضع الأداء (
config.use_performance_mode()): لا يُضمن ترتيب الصفوف في أي عملية. راجع وضع الأداء.
5. لا توجد معلمة باسم inplace
pandas
df.drop(columns=['col'], inplace=True) # Modifies df
df.fillna(0, inplace=True) # Modifies df
df.rename(columns={'old': 'new'}, inplace=True)DataStore
inplace=True غير مدعوم. أسند النتيجة دائمًا:
ds = ds.drop(columns=['col']) # Returns new DataStore
ds = ds.fillna(0) # Returns new DataStore
ds = ds.rename(columns={'old': 'new'}) # Returns new DataStoreلماذا لا يوجد inplace؟
يستخدم DataStore عمليات غير قابلة للتعديل لإتاحة ما يلي:
- بناء الاستعلامات (التقييم المؤجل)
- السلامة في البيئات متعددة الخيوط
- تصحيح الأخطاء بسهولة أكبر
- شيفرة أكثر نظافة
6. دعم الفهارس
pandas
دعم كامل للفهارس:
df = df.set_index('id')
df.loc['user123'] # Label-based access
df.loc['a':'z'] # Label-based slicing
df.reset_index()
df.index.name = 'user_id'DataStore
دعم مبسّط للفهارس:
# Basic operations work
ds.loc[0:10] # Integer position
ds.iloc[0:10] # Same as loc for DataStore
# For pandas-style index operations, convert first
df = ds.to_df()
df = df.set_index('id')
df.loc['user123']مصدر DataStore مهم
- مصدر DataFrame: يحافظ على الفهرس في pandas
- مصدر File: يستخدم فهرسًا بسيطًا من الأعداد الصحيحة
7. سلوك عمليات المقارنة
المقارنة مع pandas
لا يتعرّف pandas على كائنات DataStore:
import pandas as pd
from chdb import datastore as ds
pdf = pd.DataFrame({'a': [1, 2, 3]})
dsf = ds.DataFrame({'a': [1, 2, 3]})
# This doesn't work as expected
pdf == dsf # pandas doesn't know DataStore
# Solution: convert DataStore to pandas
pdf.equals(dsf.to_pandas()) # Trueاستخدام الدالة equals()
# DataStore.equals() also works
dsf.equals(pdf) # Compares with pandas DataFrame8. استدلال النوع
pandas
يستخدم أنواع البيانات في numpy/pandas:
df['col'].dtype # int64, float64, object, datetime64, etc.DataStore
يمكنه استخدام أنواع ClickHouse:
ds['col'].dtype # Int64, Float64, String, DateTime, etc.
# Types are converted when going to pandas
df = ds.to_df()
df['col'].dtype # Now pandas typeالتحويل الصريح للأنواع
# Force specific type
ds['col'] = ds['col'].astype('int64')9. نموذج الذاكرة
pandas
توجد جميع البيانات في الذاكرة:
df = pd.read_csv("huge.csv") # 10GB in memory!DataStore
تبقى البيانات في المصدر إلى أن تكون مطلوبة:
ds = pd.read_csv("huge.csv") # Just metadata
ds = ds.filter(ds['year'] == 2024) # Still just metadata
# Only filtered result is loaded
df = ds.to_df() # Maybe only 1GB now10. رسائل الخطأ
مصادر الأخطاء المختلفة
- أخطاء pandas: من مكتبة pandas
- أخطاء DataStore: من chDB أو ClickHouse
# May see ClickHouse-style errors
# "Code: 62. DB::Exception: Syntax error..."نصائح لتصحيح الأخطاء
# View the SQL to debug
print(ds.to_sql())
# See execution plan
ds.explain()
# Enable debug logging
from chdb.datastore.config import config
config.enable_debug()قائمة التحقق الخاصة بالترحيل
عند الترحيل من pandas:
- غيّر عبارة الاستيراد
- أزل المعاملات
inplace=True - أضف
to_df()صراحةً حيث يكونpandas DataFrameمطلوبًا - أضف الفرز إذا كان ترتيب الصفوف مهمًا
- استخدم
to_pandas()في اختبارات المقارنة - اختبر باستخدام أحجام بيانات ممثلة
مرجع سريع
| pandas | DataStore |
|---|---|
df[condition] |
كما هو (ويُرجع DataStore) |
df.groupby() |
كما هو (ويُرجع LazyGroupBy) |
df.drop(inplace=True) |
ds = ds.drop() |
df.equals(other) |
ds.to_pandas().equals(other) |
df.loc['label'] |
ds.to_df().loc['label'] |
print(df) |
كما هو (ويؤدي إلى التنفيذ) |
len(df) |
كما هو (ويؤدي إلى التنفيذ) |