Saltar al contenido principal
Aunque DataStore es muy compatible con pandas, hay diferencias importantes que conviene entender.

Tabla resumen

AspectopandasDataStore
EjecuciónInmediataDiferida
Tipos de retornoDataFrame/SeriesDataStore/ColumnExpr
Orden de las filasSe conservaSe conserva (automáticamente); no está garantizado en el modo de rendimiento
inplaceAdmitidoNo admitido
ÍndiceCompatibilidad completaSimplificado
MemoriaTodos los datos en memoriaLos datos permanecen en el origen

1. Ejecución diferida frente a ejecución inmediata

pandas (inmediato)

Las operaciones se ejecutan de inmediato:
import pandas as pd

df = pd.read_csv("data.csv")  # Carga el archivo completo AHORA
result = df[df['age'] > 25]   # Filtra AHORA
grouped = result.groupby('city')['salary'].mean()  # Agrega AHORA

DataStore (diferido)

Las operaciones se aplazan hasta que se necesitan los resultados:
from chdb import datastore as pd

ds = pd.read_csv("data.csv")  # Solo registra la fuente
result = ds[ds['age'] > 25]   # Solo registra el filtro
grouped = result.groupby('city')['salary'].mean()  # Solo registra

# La ejecución ocurre aquí:
print(grouped)        # Se ejecuta al mostrar
df = grouped.to_df()  # O al convertir a pandas

Por qué es importante

La ejecución diferida permite:
  • Optimización de consultas: Varias operaciones se compilan en una sola consulta SQL
  • Poda de columnas: Solo se leen las columnas necesarias
  • Ejecución de filtros en el origen: Los filtros se aplican en el origen
  • Uso eficiente de la memoria: No se cargan datos innecesarios

2. Tipos de retorno

pandas

df['col']           # Devuelve pd.Series
df[['a', 'b']]      # Devuelve pd.DataFrame
df[df['x'] > 10]    # Devuelve pd.DataFrame
df.groupby('x')     # Devuelve DataFrameGroupBy

DataStore

ds['col']           # Devuelve ColumnExpr (lazy)
ds[['a', 'b']]      # Devuelve DataStore (lazy)
ds[ds['x'] > 10]    # Devuelve DataStore (lazy)
ds.groupby('x')     # Devuelve LazyGroupBy

Conversión a tipos de pandas

# Obtener DataFrame de pandas
df = ds.to_df()
df = ds.to_pandas()

# Obtener Series de pandas desde una columna
series = ds['col'].to_pandas()

# O disparar la ejecución
print(ds)  # Convierte automáticamente para mostrar

3. Desencadenantes de ejecución

DataStore se ejecuta cuando se necesitan valores reales:
DesencadenanteEjemploNotas
print() / repr()print(ds)La visualización requiere datos
len()len(ds)Se necesita el recuento de filas
.columnsds.columnsSe necesitan los nombres de las columnas
.dtypesds.dtypesSe necesita información sobre los tipos
.shapeds.shapeSe necesitan las dimensiones
.valuesds.valuesSe necesitan los datos reales
.indexds.indexSe necesita el índice
to_df()ds.to_df()Conversión explícita
Iteraciónfor row in dsSe necesita iterar
equals()ds.equals(other)Se necesita la comparación

Operaciones que permanecen diferidas

OperaciónDevuelve
filter()DataStore
select()DataStore
sort()DataStore
groupby()LazyGroupBy
join()DataStore
ds['col']ColumnExpr
ds[['a', 'b']]DataStore
ds[condition]DataStore

4. Orden de filas

pandas

El orden de las filas siempre se mantiene:
df = pd.read_csv("data.csv")
print(df.head())  # Siempre en el mismo orden que el archivo

DataStore

El orden de las filas se conserva automáticamente en la mayoría de las operaciones:
ds = pd.read_csv("data.csv")
print(ds.head())  # Coincide con el orden del archivo

# El filtro conserva el orden
ds_filtered = ds[ds['age'] > 25]  # Mismo orden que pandas
DataStore rastrea automáticamente las posiciones originales de las filas de forma interna (mediante rowNumberInAllBlocks()) para garantizar la coherencia del orden con pandas.

Cuando se conserva el orden

  • Fuentes de archivos (CSV, Parquet, JSON, etc.)
  • Fuentes de DataFrame de pandas
  • Operaciones de filtro
  • Selección de columnas
  • Después de una llamada explícita a sort() o sort_values()
  • Operaciones que definen el orden (nlargest(), nsmallest(), head(), tail())

Cuándo el orden puede variar

  • Después de las agregaciones de groupby() (utilice sort_values() para garantizar un orden coherente)
  • Después de merge() / join() con ciertos tipos de join
  • En modo de rendimiento (config.use_performance_mode()): el orden de las filas no está garantizado en ninguna operación. Consulte Modo de rendimiento.

5. Sin parámetro inplace

pandas

df.drop(columns=['col'], inplace=True)  # Modifica df
df.fillna(0, inplace=True)              # Modifica df
df.rename(columns={'old': 'new'}, inplace=True)

DataStore

inplace=True no se admite. Asigna siempre el resultado:
ds = ds.drop(columns=['col'])           # Devuelve un nuevo DataStore
ds = ds.fillna(0)                       # Devuelve un nuevo DataStore
ds = ds.rename(columns={'old': 'new'})  # Devuelve un nuevo DataStore

¿Por qué no usar inplace?

DataStore usa operaciones inmutables para favorecer:
  • La construcción de consultas (evaluación diferida)
  • La seguridad en entornos multihilo
  • Una depuración más sencilla
  • Un código más limpio

6. Soporte de índices

pandas

Compatibilidad completa con índices:
df = df.set_index('id')
df.loc['user123']           # Acceso basado en etiquetas
df.loc['a':'z']             # Segmentación basada en etiquetas
df.reset_index()
df.index.name = 'user_id'

DataStore

Soporte simplificado para índices:
# Las operaciones básicas funcionan
ds.loc[0:10]               # Posición entera
ds.iloc[0:10]              # Igual que loc para DataStore

# Para operaciones de índice estilo pandas, convertir primero
df = ds.to_df()
df = df.set_index('id')
df.loc['user123']

La fuente de DataStore importa

  • Fuente DataFrame: Conserva el índice de pandas
  • Fuente File: Usa un índice entero simple

7. Comportamiento de las comparaciones

Comparación con pandas

pandas no reconoce los objetos 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]})

# Esto no funciona como se espera
pdf == dsf  # pandas no reconoce DataStore

# Solución: convertir DataStore a pandas
pdf.equals(dsf.to_pandas())  # True

Uso de equals()

# DataStore.equals() también funciona
dsf.equals(pdf)  # Compara con un DataFrame de pandas

8. Inferencia de tipos

pandas

Utiliza tipos de numpy/pandas:
df['col'].dtype  # int64, float64, object, datetime64, etc.

DataStore

Puede utilizar tipos de ClickHouse:
ds['col'].dtype  # Int64, Float64, String, DateTime, etc.

# Los tipos se convierten al pasar a pandas
df = ds.to_df()
df['col'].dtype  # Ahora es tipo pandas

Conversión explícita

# Forzar tipo específico
ds['col'] = ds['col'].astype('int64')

9. Modelo de memoria

pandas

Todos los datos se almacenan en memoria:
df = pd.read_csv("huge.csv")  # ¡10 GB en memoria!

DataStore

Los datos permanecen en su origen hasta que se necesitan:
ds = pd.read_csv("huge.csv")  # Solo metadatos
ds = ds.filter(ds['year'] == 2024)  # Todavía solo metadatos

# Solo se carga el resultado filtrado
df = ds.to_df()  # Quizás solo 1 GB ahora

10. Mensajes de error

Diferentes fuentes de errores

  • errores de pandas: De la biblioteca pandas
  • errores de DataStore: De chDB o ClickHouse
# Es posible ver errores de estilo ClickHouse
# "Code: 62. DB::Exception: Syntax error..."

Consejos de depuración

# Ver el SQL para depurar
print(ds.to_sql())

# Ver el plan de ejecución
ds.explain()

# Habilitar el registro de depuración
from chdb.datastore.config import config
config.enable_debug()

Lista de comprobación para la migración

Al migrar desde pandas:
  • Cambie la instrucción de importación
  • Elimine los parámetros inplace=True
  • Añada to_df() de forma explícita cuando se requiera un DataFrame de pandas
  • Añada ordenación si el orden de las filas es importante
  • Use to_pandas() para las pruebas de comparación
  • Haga pruebas con tamaños de datos representativos

Referencia rápida

pandasDataStore
df[condition]Igual (devuelve DataStore)
df.groupby()Igual (devuelve 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)Igual (ejecuta la operación)
len(df)Igual (ejecuta la operación)
Última modificación el 10 de junio de 2026