DataStoreは、完全なAPI互換性を実現するために209のpandas DataFrameメソッドを実装しています。既存のpandasコードも、最小限の変更で動作します。
互換性の考え方
# Typical migration - just change the import
- import pandas as pd
+ from chdb import datastore as pd
# Your code works unchanged
df = pd.read_csv("data.csv")
result = df[df['age'] > 25].groupby('city')['salary'].mean()主な原則:
- pandas DataFrame の 209 個のメソッドをすべて実装
- 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() |
Dtype による選択 | ds.select_dtypes(include='number') |
df.query() |
クエリ式 | ds.query('age > 25') |
df.where() |
条件付き置換 | ds.where(ds['age'] > 0, 0) |
df.mask() |
where の逆 |
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') |
統計メソッド
| Method | 説明 | 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")
# Basic statistics
print(ds['salary'].mean())
print(ds['age'].std())
print(ds.describe())
# Group statistics
print(ds.groupby('department')['salary'].mean())
print(ds.groupby('city').agg({'salary': ['mean', 'std'], 'age': 'count'}))データ操作
| Method | 説明 |
|---|---|
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")
# Drop operations
result = ds.drop(columns=['unused_col'])
result = ds.drop_duplicates(subset=['user_id'])
result = ds.dropna(subset=['email'])
# Fill operations
result = ds.fillna(0)
result = ds.fillna({'age': 0, 'name': 'Unknown'})
# Transform operations
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])
)ソートと順位付け
| Method | Description |
|---|---|
sort_values() |
値でソート |
sort_index() |
索引でソート |
nlargest() |
大きい値の上位 N 件 |
nsmallest() |
小さい値の上位 N 件 |
例:
# Sort by single column
result = ds.sort_values('salary', ascending=False)
# Sort by multiple columns
result = ds.sort_values(['department', 'salary'], ascending=[True, False])
# Get top/bottom N
result = ds.nlargest(10, 'salary')
result = ds.nsmallest(5, 'age')形状変更
| Method | Description |
|---|---|
pivot() |
ピボットテーブル |
pivot_table() |
集約を伴うピボット |
melt() |
アンピボット |
stack() |
カラムを索引に積み上げる |
unstack() |
索引をカラムに展開する |
transpose() / T |
転置 |
explode() |
リストを行に展開する |
squeeze() |
次元を削減する |
droplevel() |
索引レベルを削除する |
swaplevel() |
索引レベルを入れ替える |
reorder_levels() |
レベルを並べ替える |
例:
# Pivot table
result = ds.pivot_table(
values='amount',
index='region',
columns='product',
aggfunc='sum'
)
# Melt (unpivot)
result = ds.melt(
id_vars=['name'],
value_vars=['score1', 'score2', 'score3'],
var_name='test',
value_name='score'
)
# Explode arrays
result = ds.explode('tags')結合 / JOIN
| Method | Description |
|---|---|
merge() |
SQLスタイルのマージ |
join() |
索引で結合 |
concat() |
連結 |
append() |
行を追加 |
combine() |
関数を使って結合 |
combine_first() |
優先順位に従って結合 |
update() |
値を更新 |
compare() |
差分を表示 |
例:
# Merge (join)
result = pd.merge(df1, df2, on='id', how='left')
result = df1.join(df2, on='id')
# Concatenate
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() |
行列積 |
例:
# Arithmetic operations
result = ds['col1'].add(ds['col2'])
result = ds['price'].mul(ds['quantity'])
# With fill_value for missing data
result = ds['col1'].add(ds['col2'], fill_value=0)比較操作
| メソッド | 説明 |
|---|---|
eq() |
等しい |
ne() |
等しくない |
lt() |
未満 |
le() |
以下 |
gt() |
より大きい |
ge() |
以上 |
equals() |
等しいかどうかを判定 |
compare() |
差異を表示 |
関数の適用
| メソッド | 説明 |
|---|---|
apply() |
関数を適用 |
applymap() |
要素ごとに適用 |
map() |
値をマッピング |
agg() / aggregate() |
集約 |
transform() |
変換 |
pipe() |
関数をパイプ処理 |
groupby() |
グループ化 |
例:
# Apply function
result = ds['name'].apply(lambda x: x.upper())
result = ds.apply(lambda row: row['a'] + row['b'], axis=1)
# Aggregate
result = ds.agg({'col1': 'sum', 'col2': 'mean'})
result = ds.agg(['sum', 'mean', 'std'])
# Pipe
result = (ds
.pipe(filter_active)
.pipe(calculate_metrics)
.pipe(format_output)
)時系列
| Method | Description |
|---|---|
rolling() |
ローリングウィンドウ |
expanding() |
累積ウィンドウ |
ewm() |
指数加重 |
resample() |
時系列をリサンプリング |
shift() |
値をシフト |
asfreq() |
頻度を変換 |
asof() |
指定時点での最新値 |
at_time() |
特定時刻を選択 |
between_time() |
時間帯を選択 |
first() / last() |
先頭/末尾の期間 |
to_period() |
期間に変換 |
to_timestamp() |
タイムスタンプに変換 |
tz_convert() |
タイムゾーンを変換 |
tz_localize() |
タイムゾーンを設定 |
例:
# Rolling window
result = ds['value'].rolling(window=7).mean()
# Expanding window
result = ds['value'].expanding().sum()
# Shift
result = ds['value'].shift(1) # Lag
result = ds['value'].shift(-1) # Lead欠損データ
| メソッド | 説明 |
|---|---|
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() |
Dictionary |
to_records() |
レコード |
to_numpy() |
NumPy 配列 |
to_clipboard() |
クリップボード |
詳細は I/O 操作 を参照してください。
反復処理
| メソッド | 説明 |
|---|---|
items() |
(カラム, Series) の組を反復処理 |
iterrows() |
(索引, Series) の組を反復処理 |
itertuples() |
名前付きタプルとして反復処理 |
Pandasとの主な違い
1. 戻り値の型
# Pandas returns Series
pdf['col'] # → pd.Series
# DataStore returns ColumnExpr (lazy)
ds['col'] # → ColumnExpr2. 遅延実行
# DataStore operations are lazy
result = ds.filter(ds['age'] > 25) # Not executed yet
df = result.to_df() # Executed here3. inplace パラメータはない
# Pandas
df.drop(columns=['col'], inplace=True)
# DataStore (always returns new object)
ds = ds.drop(columns=['col'])4. 結果の比較
# Use to_pandas() for comparison
pd.testing.assert_frame_equal(
ds.to_pandas(),
expected_df
)詳細については、主な違いをご覧ください。