use greeners_core::dataframe::DataFrame;
use indexmap::IndexMap;
fn main() {
println!("=== Advanced DataFrame Operations ===\n");
println!("Demonstrating: append_row, merge (SQL joins), and groupby\n");
println!("=== 1. APPEND_ROW - Add individual rows ===\n");
let mut sales = DataFrame::builder()
.add_column("date", vec![1.0, 2.0, 3.0])
.add_column("product", vec![1.0, 2.0, 1.0])
.add_column("revenue", vec![100.0, 150.0, 120.0])
.build()
.unwrap();
println!("Original sales data:");
println!("{}\n", sales);
let mut new_sale = IndexMap::new();
new_sale.insert("date".to_string(), 4.0);
new_sale.insert("product".to_string(), 3.0);
new_sale.insert("revenue".to_string(), 200.0);
sales = sales.append_row(&new_sale).unwrap();
println!("After appending new sale:");
println!("{}\n", sales);
println!("=== 2. MERGE - SQL-style joins ===\n");
let customers = DataFrame::builder()
.add_column("customer_id", vec![1.0, 2.0, 3.0, 4.0])
.add_column("age", vec![25.0, 30.0, 35.0, 40.0])
.add_column("region", vec![1.0, 1.0, 2.0, 2.0])
.build()
.unwrap();
let orders = DataFrame::builder()
.add_column("customer_id", vec![2.0, 3.0, 3.0, 5.0])
.add_column("order_value", vec![100.0, 150.0, 200.0, 300.0])
.add_column("quantity", vec![2.0, 3.0, 4.0, 5.0])
.build()
.unwrap();
println!("Customers:");
println!("{}\n", customers);
println!("Orders:");
println!("{}\n", orders);
println!("--- INNER JOIN ---");
println!("Only customers who have placed orders:");
let inner = customers.merge(&orders, "customer_id", "inner").unwrap();
println!("{}\n", inner);
println!("--- LEFT JOIN ---");
println!("All customers, with order info (NaN if no orders):");
let left = customers.merge(&orders, "customer_id", "left").unwrap();
println!("{}\n", left);
println!("--- RIGHT JOIN ---");
println!("All orders, with customer info (NaN if customer not found):");
let right = customers.merge(&orders, "customer_id", "right").unwrap();
println!("{}\n", right);
println!("--- OUTER JOIN ---");
println!("All customers and all orders (NaN where no match):");
let outer = customers.merge(&orders, "customer_id", "outer").unwrap();
println!("{}\n", outer);
println!("=== 3. GROUPBY - Aggregations ===\n");
let transactions = DataFrame::builder()
.add_column("category", vec![1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0])
.add_column("region", vec![1.0, 1.0, 2.0, 1.0, 2.0, 2.0, 1.0, 2.0])
.add_column(
"revenue",
vec![100.0, 150.0, 200.0, 300.0, 250.0, 400.0, 500.0, 350.0],
)
.add_column(
"quantity",
vec![5.0, 7.0, 10.0, 15.0, 12.0, 20.0, 25.0, 18.0],
)
.build()
.unwrap();
println!("Transaction data:");
println!("{}\n", transactions);
println!("--- Total revenue by category ---");
let by_category = transactions
.groupby(&["category"], "revenue", "sum")
.unwrap();
println!("{}\n", by_category);
println!("--- Transaction count by category ---");
let count_by_cat = transactions
.groupby(&["category"], "revenue", "count")
.unwrap();
println!("{}\n", count_by_cat);
println!("--- Average revenue by category ---");
let avg_by_cat = transactions
.groupby(&["category"], "revenue", "mean")
.unwrap();
println!("{}\n", avg_by_cat);
println!("--- Total revenue by region ---");
let by_region = transactions.groupby(&["region"], "revenue", "sum").unwrap();
println!("{}\n", by_region);
println!("--- Total revenue by category AND region ---");
let by_both = transactions
.groupby(&["category", "region"], "revenue", "sum")
.unwrap();
println!("{}\n", by_both);
println!("--- Maximum revenue by category ---");
let max_by_cat = transactions
.groupby(&["category"], "revenue", "max")
.unwrap();
println!("{}\n", max_by_cat);
println!("--- Minimum revenue by category ---");
let min_by_cat = transactions
.groupby(&["category"], "revenue", "min")
.unwrap();
println!("{}\n", min_by_cat);
println!("--- Median revenue by category ---");
let median_by_cat = transactions
.groupby(&["category"], "revenue", "median")
.unwrap();
println!("{}\n", median_by_cat);
println!("=== 4. REAL-WORLD WORKFLOW - Combining Operations ===\n");
println!("Scenario: Analyze customer orders by region\n");
let customer_orders = customers.merge(&orders, "customer_id", "inner").unwrap();
println!("Step 1: Join customers with their orders");
println!("{}\n", customer_orders);
let region_analysis = customer_orders
.groupby(&["region"], "order_value", "sum")
.unwrap();
println!("Step 2: Total order value by region");
println!("{}\n", region_analysis);
let region_count = customer_orders
.groupby(&["region"], "order_value", "count")
.unwrap();
println!("Step 3: Number of orders by region");
println!("{}\n", region_count);
let region_avg = customer_orders
.groupby(&["region"], "order_value", "mean")
.unwrap();
println!("Step 4: Average order value by region");
println!("{}\n", region_avg);
let mut high_value_order = IndexMap::new();
high_value_order.insert("customer_id".to_string(), 1.0);
high_value_order.insert("order_value".to_string(), 500.0);
high_value_order.insert("quantity".to_string(), 10.0);
let orders_updated = orders.append_row(&high_value_order).unwrap();
let updated_analysis = customers
.merge(&orders_updated, "customer_id", "inner")
.unwrap()
.groupby(&["region"], "order_value", "sum")
.unwrap();
println!("Step 5: After adding high-value order");
println!("{}\n", updated_analysis);
println!("=== Summary of Capabilities ===");
println!("✅ append_row: Add individual records dynamically");
println!("✅ merge: 4 join types (inner, left, right, outer)");
println!("✅ groupby: 6 aggregations (sum, mean, count, min, max, median)");
println!("✅ Multi-column grouping supported");
println!("✅ Chain operations for complex workflows");
println!("\n=== Demo Complete! ===");
}