Pandas Aggregation을 대체하는 RDB 라이브러리, DuckDB

Pandas Aggregation을 대체하는 RDB 라이브러리, DuckDB
Photo by Christian Bowen / Unsplash

Data Prep

Code

  • Pandas
    • Single Threaded Library
import os  
import pandas as pd  
  
  
# Load the data  
base_path = "path/to/the/folder"  
parquet_files = [os.path.join(base_path, file) for file in os.listdir(base_path) if file.endswith('.parquet')]  
dfs = [pd.read_parquet(file) for file in parquet_files]  
df_pd = pd.concat(dfs, ignore_index=True)  
  
# Benchmark function  
def calculate_monthly_taxi_stats_pandas(df: pd.DataFrame) -> pd.DataFrame:  
	df = (  
		df  
			.assign(  
			trip_year=df["tpep_pickup_datetime"].dt.strftime("%Y").astype("int32"),  
			period=df["tpep_pickup_datetime"].dt.strftime("%Y-%m"),  
			trip_duration=(df["tpep_dropoff_datetime"] - df["tpep_pickup_datetime"]).dt.total_seconds()  
			)  
			.query(f"trip_year >= 2021 and trip_year <= 2024")  
			.loc[:, ["period", "trip_duration", "trip_distance", "total_amount", "tip_amount"]]  
			.groupby("period")  
			.agg({  
			"trip_duration": ["count", "mean"],  
			"trip_distance": ["mean", "sum"],  
			"total_amount": ["mean", "sum"],  
			"tip_amount": ["mean"]  
			})  
	)  
	df.columns = df.columns.get_level_values(level=1)  
	df = df.reset_index()  
	df.columns = ["period", "num_rides", "avg_trip_duration", "avg_trip_distance", "total_trip_distance", "avg_trip_price", "total_trip_price", "avg_tip_amount"]  
	df = df.sort_values(by="period")  
	return df  
  
  
# Run  
res_pandas = calculate_monthly_taxi_stats_pandas(df=df_pd)
  • DuckDB
    • parquet_scan()f로 Parquet Read 지원
import duckdb  
  
  
# Database connection  
conn = duckdb.connect()  
  
# Benchmark function  
def calculate_monthly_taxi_stats_duckdb(conn: duckdb.DuckDBPyConnection, path: str) -> pd.DataFrame:  
	return (  
		conn.sql(f"""  
			select  
				period,  
				count(*) AS num_rides,  
				round(avg(trip_duration), 2) AS avg_trip_duration,  
				round(avg(trip_distance), 2) AS avg_trip_distance,  
				round(sum(trip_distance), 2) as total_trip_distance,  
				round(avg(total_amount), 2) as avg_trip_price,  
				round(sum(total_amount), 2) as total_trip_price,  
				round(avg(tip_amount), 2) as avg_tip_amount  
				from (  
					select  
						date_part('year', tpep_pickup_datetime) as trip_year,  
						strftime(tpep_pickup_datetime, '%Y-%m') as period,  
						epoch(tpep_dropoff_datetime - tpep_pickup_datetime) as trip_duration,  
						trip_distance,  
						total_amount,  
						tip_amount  
						from parquet_scan("{path}")  
					where trip_year >= 2021 and trip_year <= 2024  
			)  
			group by period  
			order by period  
			""").df()  
	)  
  
  
# Run  
res_duckdb = calculate_monthly_taxi_stats_duckdb(conn=conn, path="path/to/the/folder/*parquet")

Result

  • Parquet Load 이후, Monthly Stat Summary하는 형태로 Test

Limitation

Reference

Read more

다중공선성은 잘못된 인과추론 결과를 만들어낼 수 있습니다.

다중공선성은 잘못된 인과추론 결과를 만들어낼 수 있습니다.

다중공선성(Multi Collinearity) * **Multi-Collinearity(다중공선성)**는 독립 변수들 간의 강한 상관관계가 존재할 때 발생합니다. 즉, 한 독립 변수가 다른 독립 변수에 의해 설명될 수 있을 정도로 상관관계가 높은 상황을 의미합니다. * 이 문제는 주로 회귀 분석에서 나타나며, 변수들 간의 관계를 해석하는 데 있어 큰 장애물이 될 수 있습니다. * 일반적인 회귀식을 $Y=

Bayesian P-Value는 불확실성을 감안하여 모델의 적합도를 평가합니다.

Bayesian P-Value는 불확실성을 감안하여 모델의 적합도를 평가합니다.

Bayesian P- Value * Bayesian P-Value는 **모델의 적합도(goodness-of-fit)**를 평가하는 데 사용됩니다. * 사후 분포(posterior distribution)를 이용하여 실제 데이터와 모델이 생성한 예상 데이터를 비교함으로써, 관측된 데이터가 모델에 의해 얼마나 잘 설명되는지를 평가합니다. * 빈도주의 p-값은 "관찰된 데이터보다 극단적인 데이터가 나올 확률"을 계산하지만, Bayesian P-Value는 "모델이 실제

Non-Identifiability는 Model Parameter를 고유하게 식별할 수 없는 현상입니다.

Non-Identifiability는 Model Parameter를 고유하게 식별할 수 없는 현상입니다.

Non Identifiability * Non-Identifiability는 주어진 데이터와 모델에 대해 특정 파라미터를 고유하게 식별할 수 없는 상황을 의미합니다. 즉, 여러 파라미터 값들이 동일한 데이터를 생성할 수 있으며, 이로 인해 특정 파라미터 값을 확정적으로 추정하기 어렵게 됩니다. * 베이지안 추론에서 Non-Identifiability는 사후 분포가 특정 파라미터 값에 대해 명확하게 수렴하지 않고, 여러 값들에 대해 비슷한 확률을

Rootgram은 큰 분산을 갖거나 비정규 형태의 데이터를 위한 히스토그램입니다.

Rootgram은 큰 분산을 갖거나 비정규 형태의 데이터를 위한 히스토그램입니다.

Rootgram * 히스토그램의 변형으로 데이터가 비정규적이거나 큰 분산을 가지는 경우, 정확한 분포를 파악하기 위해 사용됩니다. * 일반적으로 히스토그램은 데이터의 빈도를 직접적으로 나타내기 때문에, 큰 값이 빈번하게 발생하는 경우 상대적으로 작은 값을 잘 드러내지 못하는 경향이 있습니다. 반면, Rootgram은 빈도를 제곱근 형태로 변환하여, 데이터 분포의 차이를 더 잘 시각화할 수 있도록 돕습니다 * 여기서