Подход к обеспечению совместимости
# Типичная миграция — просто измените импорт
- import pandas as pd
+ from chdb import datastore as pd
# Ваш код работает без изменений
df = pd.read_csv("data.csv")
result = df[df['age'] > 25].groupby('city')['salary'].mean()
- Реализованы все 209 методов pandas DataFrame
- Отложенное вычисление для оптимизации SQL
- Автоматическое приведение типов (DataFrame → DataStore, Series → ColumnExpr)
- Неизменяемые операции (без
inplace=True)
Атрибуты и свойства
| Свойство | Описание | Запускает выполнение |
|---|---|---|
shape | кортеж (строки, столбцы) | Да |
columns | Имена столбцов (Index) | Да |
dtypes | Типы данных столбцов | Да |
values | массив NumPy | Да |
index | Индекс строк | Да |
size | Количество элементов | Да |
ndim | Число размерностей | Нет |
empty | Пуст ли DataFrame | Да |
T | Транспонирование | Да |
axes | Список осей | Да |
from chdb import datastore as pd
ds = pd.read_csv("data.csv")
print(ds.shape) # (1000, 5)
print(ds.columns) # Index(['name', 'age', 'city', 'salary', 'dept'])
print(ds.dtypes) # name: object, age: int64, ...
print(ds.empty) # False
Индексирование и выбор
| Метод | Описание | Пример |
|---|---|---|
df['col'] | Выбор столбца | ds['age'] |
df[['col1', 'col2']] | Выбор столбцов | ds[['name', 'age']] |
df[condition] | Булево индексирование | ds[ds['age'] > 25] |
df.loc[...] | Доступ по меткам | ds.loc[0:10, 'name'] |
df.iloc[...] | Доступ по целочисленным позициям | ds.iloc[0:10, 0:3] |
df.at[...] | Одно значение по метке | ds.at[0, 'name'] |
df.iat[...] | Одно значение по позиции | ds.iat[0, 0] |
df.head(n) | Первые n строк | ds.head(10) |
df.tail(n) | Последние n строк | ds.tail(10) |
df.sample(n) | Случайная выборка | ds.sample(100) |
df.select_dtypes() | Выбор по типу данных | ds.select_dtypes(include='number') |
df.query() | Выражение запроса | ds.query('age > 25') |
df.where() | Условная замена | ds.where(ds['age'] > 0, 0) |
df.mask() | Обратное условие | ds.mask(ds['age'] < 0, 0) |
df.isin() | Проверка принадлежности значения | ds['city'].isin(['NYC', 'LA']) |
df.get() | Безопасный доступ к столбцу | ds.get('col', default=None) |
df.xs() | Поперечное сечение | ds.xs('key') |
df.pop() | Удаление столбца | ds.pop('col') |
Статистические методы
| Метод | Описание | Эквивалент SQL |
|---|---|---|
mean() | Среднее значение | AVG() |
median() | Медиана | MEDIAN() |
mode() | Мода | - |
std() | Стандартное отклонение | STDDEV() |
var() | Дисперсия | VAR() |
min() | Минимум | MIN() |
max() | Максимум | MAX() |
sum() | Сумма | SUM() |
prod() | Произведение | - |
count() | Количество значений, отличных от NULL | COUNT() |
nunique() | Количество уникальных значений | UNIQ() |
value_counts() | Частота значений | GROUP BY |
quantile() | Квантиль | QUANTILE() |
describe() | Сводная статистика | - |
corr() | Матрица корреляции | CORR() |
cov() | Матрица ковариации | COV() |
corrwith() | Попарная корреляция | - |
rank() | Ранжирование значений | RANK() |
abs() | Абсолютные значения | ABS() |
round() | Округление значений | ROUND() |
clip() | Ограничение значений | - |
cumsum() | Накопительная сумма | Оконная функция |
cumprod() | Накопительное произведение | Оконная функция |
cummin() | Накопительный минимум | Оконная функция |
cummax() | Накопительный максимум | Оконная функция |
diff() | Разность | Оконная функция |
pct_change() | Процентное изменение | Оконная функция |
skew() | Асимметрия | SKEW() |
kurt() | Эксцесс | KURT() |
sem() | Стандартная ошибка | - |
all() | Все значения true | - |
any() | Хотя бы одно значение true | - |
idxmin() | Индекс минимума | - |
idxmax() | Индекс максимума | - |
ds = pd.read_csv("data.csv")
# Основная статистика
print(ds['salary'].mean())
print(ds['age'].std())
print(ds.describe())
# Групповая статистика
print(ds.groupby('department')['salary'].mean())
print(ds.groupby('city').agg({'salary': ['mean', 'std'], 'age': 'count'}))
Манипуляции с данными
| Метод | Описание |
|---|---|
drop() | Удалить строки/столбцы |
drop_duplicates() | Удалить дубликаты |
duplicated() | Пометить дубликаты |
dropna() | Удалить пропущенные значения |
fillna() | Заполнить пропущенные значения |
ffill() | Заполнение вперёд |
bfill() | Заполнение назад |
interpolate() | Интерполировать значения |
replace() | Заменить значения |
rename() | Переименовать столбцы/индекс |
rename_axis() | Переименовать ось |
assign() | Добавить новые столбцы |
astype() | Преобразовать типы |
convert_dtypes() | Определить типы |
copy() | Скопировать DataFrame |
ds = pd.read_csv("data.csv")
# Операции удаления
result = ds.drop(columns=['unused_col'])
result = ds.drop_duplicates(subset=['user_id'])
result = ds.dropna(subset=['email'])
# Операции заполнения
result = ds.fillna(0)
result = ds.fillna({'age': 0, 'name': 'Unknown'})
# Операции преобразования
result = ds.rename(columns={'old_name': 'new_name'})
result = ds.assign(
full_name=lambda x: x['first_name'] + ' ' + x['last_name'],
age_group=lambda x: pd.cut(x['age'], bins=[0, 25, 50, 100])
)
Сортировка и ранжирование
| Метод | Описание |
|---|---|
sort_values() | Сортировка по значениям |
sort_index() | Сортировка по индексу |
nlargest() | N наибольших значений |
nsmallest() | N наименьших значений |
# Сортировка по одному столбцу
result = ds.sort_values('salary', ascending=False)
# Сортировка по нескольким столбцам
result = ds.sort_values(['department', 'salary'], ascending=[True, False])
# Получить N наибольших/наименьших значений
result = ds.nlargest(10, 'salary')
result = ds.nsmallest(5, 'age')
Преобразование формы данных
| Метод | Описание |
|---|---|
pivot() | Сводная таблица |
pivot_table() | Сводная таблица с агрегацией |
melt() | Преобразование из широкого формата в длинный |
stack() | Преобразование столбцов в индекс |
unstack() | Преобразование индекса в столбцы |
transpose() / T | Транспонирование |
explode() | Преобразование списков в строки |
squeeze() | Уменьшение размерности |
droplevel() | Удаление уровня индекса |
swaplevel() | Перестановка уровней индекса |
reorder_levels() | Изменение порядка уровней |
# Сводная таблица
result = ds.pivot_table(
values='amount',
index='region',
columns='product',
aggfunc='sum'
)
# Melt (обратное преобразование сводной таблицы)
result = ds.melt(
id_vars=['name'],
value_vars=['score1', 'score2', 'score3'],
var_name='test',
value_name='score'
)
# Развернуть массивы
result = ds.explode('tags')
Комбинирование / JOIN
| Method | Description |
|---|---|
merge() | Слияние в стиле SQL |
join() | JOIN по индексу |
concat() | Конкатенация |
append() | Добавление строк |
combine() | Объединение с помощью функции |
combine_first() | Объединение с приоритетом |
update() | Обновление значений |
compare() | Показать различия |
# Слияние (JOIN)
result = pd.merge(df1, df2, on='id', how='left')
result = df1.join(df2, on='id')
# Конкатенация
result = pd.concat([df1, df2, df3])
result = pd.concat([df1, df2], axis=1)
Бинарные операции
| Метод | Описание |
|---|---|
add() / radd() | Сложение |
sub() / rsub() | Вычитание |
mul() / rmul() | Умножение |
div() / rdiv() | Деление |
truediv() / rtruediv() | Истинное деление |
floordiv() / rfloordiv() | Целочисленное деление |
mod() / rmod() | Остаток от деления |
pow() / rpow() | Возведение в степень |
dot() | Матричное умножение |
# Арифметические операции
result = ds['col1'].add(ds['col2'])
result = ds['price'].mul(ds['quantity'])
# С fill_value для отсутствующих данных
result = ds['col1'].add(ds['col2'], fill_value=0)
Операции сравнения
| Метод | Описание |
|---|---|
eq() | Равно |
ne() | Не равно |
lt() | Меньше |
le() | Меньше или равно |
gt() | Больше |
ge() | Больше или равно |
equals() | Проверка на равенство |
compare() | Показывает различия |
Применение функций
| Method | Description |
|---|---|
apply() | Применение функции |
applymap() | Поэлементное применение |
map() | Отображение значений |
agg() / aggregate() | Агрегация |
transform() | Преобразование |
pipe() | Объединение функций |
groupby() | Группировка по |
# Применить функцию
result = ds['name'].apply(lambda x: x.upper())
result = ds.apply(lambda row: row['a'] + row['b'], axis=1)
# Агрегация
result = ds.agg({'col1': 'sum', 'col2': 'mean'})
result = ds.agg(['sum', 'mean', 'std'])
# Пайп
result = (ds
.pipe(filter_active)
.pipe(calculate_metrics)
.pipe(format_output)
)
Временные ряды
| Метод | Описание |
|---|---|
rolling() | Скользящее окно |
expanding() | Нарастающее окно |
ewm() | Экспоненциальное взвешивание |
resample() | Передискретизация временного ряда |
shift() | Сдвиг значений |
asfreq() | Преобразование частоты |
asof() | Последнее значение на момент |
at_time() | Выбор по времени |
between_time() | Выбор временного диапазона |
first() / last() | Первые/последние периоды |
to_period() | Преобразование в период |
to_timestamp() | Преобразование во временную метку |
tz_convert() | Смена часового пояса |
tz_localize() | Назначение часового пояса |
# Скользящее окно
result = ds['value'].rolling(window=7).mean()
# Расширяющееся окно
result = ds['value'].expanding().sum()
# Сдвиг
result = ds['value'].shift(1) # Лаг
result = ds['value'].shift(-1) # Опережение
Отсутствующие данные
| Метод | Описание |
|---|---|
isna() / isnull() | Определить отсутствующие значения |
notna() / notnull() | Определить непустые значения |
dropna() | Удалить отсутствующие значения |
fillna() | Заполнить отсутствующие значения |
ffill() | Заполнение вперёд |
bfill() | Заполнение назад |
interpolate() | Интерполяция |
replace() | Заменить значения |
Методы I/O
| Метод | Описание |
|---|---|
to_csv() | Экспорт в CSV |
to_json() | Экспорт в JSON |
to_excel() | Экспорт в Excel |
to_parquet() | Экспорт в Parquet |
to_feather() | Экспорт в Feather |
to_sql() | Экспорт в SQL-базу данных |
to_pickle() | Pickle |
to_html() | HTML-таблица |
to_latex() | Таблица LaTeX |
to_markdown() | Таблица Markdown |
to_string() | Строковое представление |
to_dict() | Словарь |
to_records() | Записи |
to_numpy() | Массив NumPy |
to_clipboard() | Буфер обмена |
Итерация
| Метод | Описание |
|---|---|
items() | Итерация по парам (столбец, Series) |
iterrows() | Итерация по парам (индекс, Series) |
itertuples() | Итерация в виде именованных кортежей |
Основные отличия от Pandas
1. Типы возвращаемых значений
# Pandas возвращает Series
pdf['col'] # → pd.Series
# DataStore возвращает ColumnExpr (отложенное вычисление)
ds['col'] # → ColumnExpr
2. Ленивое выполнение
# Операции DataStore выполняются отложенно
result = ds.filter(ds['age'] > 25) # Пока не выполняется
df = result.to_df() # Выполняется здесь
3. Параметр inplace отсутствует
# Pandas
df.drop(columns=['col'], inplace=True)
# DataStore (всегда возвращает новый объект)
ds = ds.drop(columns=['col'])
4. Сравнение результатов
# Используйте to_pandas() для сравнения
pd.testing.assert_frame_equal(
ds.to_pandas(),
expected_df
)