> ## Documentation Index
> Fetch the complete documentation index at: https://clickhouse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ключевые различия с pandas

> Важные различия между DataStore и pandas

Хотя DataStore во многом совместим с pandas, важно понимать ключевые различия.

## Сводная таблица

| Aspect | pandas | DataStore |
| - | - | - |
| **Выполнение** | Немедленное (сразу) | Отложенное (по необходимости) |
| **Возвращаемые типы** | DataFrame/Series | DataStore/ColumnExpr |
| **Порядок строк** | Сохраняется | Сохраняется (автоматически); не гарантируется в [режиме производительности](https://clickhouse.com/docs/ru/chdb/configuration/performance-mode.md) |
| **inplace** | Поддерживается | Не поддерживается |
| **Индекс** | Полная поддержка | Упрощённая поддержка |
| **Память** | Все данные в памяти | Данные остаются в источнике |

***

## 1. Отложенное и немедленное выполнение

### pandas (немедленное выполнение)

Operations выполняются сразу:

```python theme={null}
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 NOW
```

### DataStore (отложенное выполнение)

Выполнение операций откладывается до тех пор, пока не потребуются результаты:

```python theme={null}
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-запрос
* **Отсечение столбцов**: Считываются только необходимые столбцы
* **Pushdown фильтров**: Фильтры применяются на стороне источника
* **Эффективное использование памяти**: Загружаются только нужные данные

***

## 2. Типы возвращаемых значений

### pandas

```python theme={null}
df['col']           # Returns pd.Series
df[['a', 'b']]      # Returns pd.DataFrame
df[df['x'] > 10]    # Returns pd.DataFrame
df.groupby('x')     # Returns DataFrameGroupBy
```

### DataStore

```python theme={null}
ds['col']           # Returns ColumnExpr (lazy)
ds[['a', 'b']]      # Returns DataStore (lazy)
ds[ds['x'] > 10]    # Returns DataStore (lazy)
ds.groupby('x')     # Returns LazyGroupBy
```

### Преобразование в типы pandas

```python theme={null}
# 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 display
```

***

## 3. Триггеры выполнения

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

Порядок строк всегда сохраняется:

```python theme={null}
df = pd.read_csv("data.csv")
print(df.head())  # Always same order as file
```

### DataStore

Порядок строк **автоматически сохраняется** в большинстве операций:

```python theme={null}
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()` с некоторыми типами JOIN
* В **режиме производительности** (`config.use_performance_mode()`): порядок строк не гарантируется для любых операций. См. [режим производительности](https://clickhouse.com/docs/ru/chdb/configuration/performance-mode.md).

***

## 5. Параметр inplace отсутствует

### pandas

```python theme={null}
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` не поддерживается. Всегда присваивайте результат:

```python theme={null}
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

Полная поддержка индексов:

```python theme={null}
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

Упрощённая поддержка индексов:

```python theme={null}
# 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:

```python theme={null}
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()

```python theme={null}
# DataStore.equals() also works
dsf.equals(pdf)  # Compares with pandas DataFrame
```

***

## 8. Вывод типов

### pandas

Используются типы numpy/pandas:

```python theme={null}
df['col'].dtype  # int64, float64, object, datetime64, etc.
```

### DataStore

Может использовать типы данных ClickHouse:

```python theme={null}
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
```

### Явное приведение типов

```python theme={null}
# Force specific type
ds['col'] = ds['col'].astype('int64')
```

***

## 9. Модель памяти

### pandas

Все данные хранятся в памяти:

```python theme={null}
df = pd.read_csv("huge.csv")  # 10GB in memory!
```

### DataStore

Данные остаются в источнике, пока они не понадобятся:

```python theme={null}
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 now
```

***

## 10. Сообщения об ошибках

### Различные источники ошибок

* **ошибки pandas**: Из библиотеки pandas
* **ошибки DataStore**: Из chDB или ClickHouse

```python theme={null}
# May see ClickHouse-style errors
# "Code: 62. DB::Exception: Syntax error..."
```

### Советы по отладке

```python theme={null}
# 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:

* [ ] Измените инструкцию import
* [ ] Уберите параметры `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)` | То же (запускает выполнение) |
