Example 33
intermediate
33
DataFrame

DataFrame Advanced Features

Advanced DataFrame operations new in v1.0.0: string/datetime accessors, rolling/expanding/EWM windows, query/eval expressions, pivot tables, crosstabs, and more. This example uses deepbox/dataframe and focuses on Series.str, Series.dt, rolling, expanding, ewm, query, eval, assign, pivot_table, crosstab, nlargest, nsmallest, interpolate.

Deepbox Modules Used

deepbox/dataframe

What You Will Learn

  • Use deepbox/dataframe for Series.str, Series.dt, rolling, expanding, ewm, query, eval, assign, pivot_table, crosstab, nlargest, nsmallest, interpolate.
  • Advanced DataFrame operations new in v1.0.0: string/datetime accessors, rolling/expanding/EWM windows, query/eval expressions, pivot tables, crosstabs, and more.

Source Files

index.ts
1/**2 * Example 33: Advanced DataFrame Features3 *4 * New in v1.0.0: String and DateTime accessors, rolling/expanding/EWM windows,5 * query/eval expressions, pivot tables, crosstabs, interpolation, and more.6 */78import { DataFrame, Series } from "deepbox/dataframe";910console.log("=".repeat(60));11console.log("Example 33: Advanced DataFrame Features");12console.log("=".repeat(60));1314// ============================================================================15// Part 1: Series String Accessor (str)16// ============================================================================17console.log("\n📝 Part 1: Series String Accessor");18console.log("-".repeat(60));1920// The .str accessor provides vectorized string operations on Series21const names = new Series(["Alice Smith", "bob jones", "CHARLIE BROWN", null, "diana prince"]);2223console.log("Original names:");24console.log(names.toString());2526// Case transformations27const upper = names.str.upper();28console.log("\n.str.upper():", upper.toString());2930const lower = names.str.lower();31console.log(".str.lower():", lower.toString());3233const title = names.str.title();34console.log(".str.title():", title.toString());3536// String matching37const containsI = names.str.contains("i");38console.log("\n.str.contains('i'):", containsI.toString());3940// String operations41const lengths = names.str.len();42console.log(".str.len():", lengths.toString());4344const replaced = names.str.replace("o", "0");45console.log(".str.replace('o', '0'):", replaced.toString());4647const trimmed = new Series(["  hello  ", " world ", null]);48console.log("\n.str.strip():", trimmed.str.strip().toString());4950// Split and slice51const emails = new Series(["alice@example.com", "bob@test.org", null]);52console.log(".str.split('@'):", emails.str.split("@").toString());5354const starts = names.str.startswith("A");55console.log(".str.startswith('A'):", starts.toString());5657const ends = names.str.endswith("e");58console.log(".str.endswith('e'):", ends.toString());5960// ============================================================================61// Part 2: Series DateTime Accessor (dt)62// ============================================================================63console.log("\n📅 Part 2: Series DateTime Accessor");64console.log("-".repeat(60));6566// The .dt accessor provides vectorized datetime extraction on Series67const dates = new Series([68  new Date("2024-01-15T10:30:00"),69  new Date("2024-06-20T14:45:30"),70  new Date("2024-12-25T00:00:00"),71  null,72  new Date("2024-03-08T08:15:00"),73]);7475console.log("Original dates:");76console.log(dates.toString());7778// Extract date components79const years = dates.dt.year();80console.log("\n.dt.year():", years.toString());8182const months = dates.dt.month();83console.log(".dt.month():", months.toString());8485const days = dates.dt.day();86console.log(".dt.day():", days.toString());8788const hours = dates.dt.hour();89console.log(".dt.hour():", hours.toString());9091const dayOfWeek = dates.dt.dayofweek();92console.log(".dt.dayofweek():", dayOfWeek.toString());9394const quarter = dates.dt.quarter();95console.log(".dt.quarter():", quarter.toString());9697// ============================================================================98// Part 3: Rolling Window Calculations99// ============================================================================100console.log("\n📊 Part 3: Rolling Window Calculations");101console.log("-".repeat(60));102103// Rolling windows compute statistics over a sliding window104const stockPrices = new DataFrame({105  price: [100, 102, 101, 105, 108, 107, 110, 112, 109, 115],106  volume: [1000, 1200, 900, 1500, 1300, 1100, 1400, 1600, 1000, 1800],107});108109console.log("Stock price data:");110console.log(stockPrices.toString());111112// Rolling mean with window size 3113const rollingMean = stockPrices.rolling(3).mean();114console.log("\nRolling mean (window=3):");115console.log(rollingMean.toString());116117// Rolling standard deviation118const rollingStd = stockPrices.rolling(3).std();119console.log("Rolling std (window=3):");120console.log(rollingStd.toString());121122// Rolling sum123const rollingSum = stockPrices.rolling(3).sum();124console.log("Rolling sum (window=3):");125console.log(rollingSum.toString());126127// Rolling min/max128const rollingMin = stockPrices.rolling(3).min();129console.log("Rolling min (window=3):");130console.log(rollingMin.toString());131132const rollingMax = stockPrices.rolling(3).max();133console.log("Rolling max (window=3):");134console.log(rollingMax.toString());135136// ============================================================================137// Part 4: Expanding Window Calculations138// ============================================================================139console.log("\n📈 Part 4: Expanding Window Calculations");140console.log("-".repeat(60));141142// Expanding windows compute cumulative statistics from the start143const values = new DataFrame({144  revenue: [10, 20, 15, 25, 30, 18, 35, 40],145});146147const expandingMean = values.expanding().mean();148console.log("Expanding mean (cumulative average):");149console.log(expandingMean.toString());150151const expandingSum = values.expanding().sum();152console.log("Expanding sum (cumulative sum):");153console.log(expandingSum.toString());154155const expandingStd = values.expanding().std();156console.log("Expanding std (cumulative std):");157console.log(expandingStd.toString());158159// ============================================================================160// Part 5: Exponentially Weighted Moving (EWM) Calculations161// ============================================================================162console.log("\n⚡ Part 5: Exponentially Weighted Moving (EWM)");163console.log("-".repeat(60));164165// EWM gives more weight to recent observations166const temperatures = new DataFrame({167  temp: [20, 22, 21, 25, 24, 23, 26, 28, 27, 30],168});169170// Using span parameter (alpha = 2 / (span + 1))171const ewmMean = temperatures.ewm({ span: 3 }).mean();172console.log("EWM mean (span=3):");173console.log(ewmMean.toString());174175// Using direct alpha parameter176const ewmMeanAlpha = temperatures.ewm({ alpha: 0.3 }).mean();177console.log("EWM mean (alpha=0.3):");178console.log(ewmMeanAlpha.toString());179180// EWM standard deviation181const ewmStd = temperatures.ewm({ span: 3 }).std();182console.log("EWM std (span=3):");183console.log(ewmStd.toString());184185// ============================================================================186// Part 6: Query Expressions187// ============================================================================188console.log("\n🔍 Part 6: Query Expressions");189console.log("-".repeat(60));190191// Query filters rows using string expressions192const employees = new DataFrame({193  name: ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"],194  department: ["Engineering", "Sales", "Engineering", "Marketing", "Sales", "Engineering"],195  salary: [95000, 65000, 88000, 72000, 61000, 105000],196  experience: [5, 3, 4, 6, 2, 8],197});198199console.log("Employee data:");200console.log(employees.toString());201202// Simple query203const highEarners = employees.query("salary > 80000");204console.log("\nquery('salary > 80000'):");205console.log(highEarners.toString());206207// Compound query with AND208const seniorHighEarners = employees.query("salary > 70000 and experience > 4");209console.log("query('salary > 70000 and experience > 4'):");210console.log(seniorHighEarners.toString());211212// Query with OR213const salesOrMarketing = employees.query("department == Sales or department == Marketing");214console.log("query('department == Sales or department == Marketing'):");215console.log(salesOrMarketing.toString());216217// ============================================================================218// Part 7: Eval Expressions219// ============================================================================220console.log("\n🧮 Part 7: Eval Expressions");221console.log("-".repeat(60));222223// Eval creates computed columns or filters using expressions224const metrics = new DataFrame({225  a: [1, 2, 3, 4, 5],226  b: [10, 20, 30, 40, 50],227});228229console.log("Original:");230console.log(metrics.toString());231232// Create a new column with eval233const withSum = metrics.eval("c = a + b");234console.log("\neval('c = a + b'):");235console.log(withSum.toString());236237// Multiplication238const withProduct = metrics.eval("product = a * b");239console.log("eval('product = a * b'):");240console.log(withProduct.toString());241242// Filter with eval243const filtered = metrics.eval("a > 2");244console.log("eval('a > 2') — filters rows:");245console.log(filtered.toString());246247// ============================================================================248// Part 8: Assign (Functional Column Creation)249// ============================================================================250console.log("\n🔧 Part 8: Assign");251console.log("-".repeat(60));252253// Assign creates new columns from arrays or functions254const sales = new DataFrame({255  product: ["Widget", "Gadget", "Doohickey", "Thingamajig"],256  price: [10, 25, 15, 30],257  quantity: [100, 50, 80, 30],258});259260console.log("Original sales:");261console.log(sales.toString());262263// Assign with a function264const withRevenue = sales.assign({265  revenue: (row: Record<string, unknown>) => {266    const price = Number(row["price"] ?? 0);267    const qty = Number(row["quantity"] ?? 0);268    return price * qty;269  },270  discount: [0.1, 0.05, 0.15, 0.0],271});272273console.log("\nWith assigned columns (revenue, discount):");274console.log(withRevenue.toString());275276// ============================================================================277// Part 9: Pivot Table278// ============================================================================279console.log("\n📋 Part 9: Pivot Table");280console.log("-".repeat(60));281282// Pivot tables reshape data for cross-tabulation analysis283const salesData = new DataFrame({284  region: ["North", "South", "North", "South", "North", "South", "North", "South"],285  product: ["A", "A", "B", "B", "A", "A", "B", "B"],286  revenue: [100, 150, 200, 120, 130, 160, 180, 140],287});288289console.log("Sales data:");290console.log(salesData.toString());291292// Pivot: regions as rows, products as columns, mean revenue as values293const pivoted = salesData.pivot_table({294  index: "region",295  columns: "product",296  values: "revenue",297  aggFunc: "mean",298});299300console.log("\nPivot table (mean revenue by region × product):");301console.log(pivoted.toString());302303// Pivot with sum aggregation304const pivotedSum = salesData.pivot_table({305  index: "region",306  columns: "product",307  values: "revenue",308  aggFunc: "sum",309});310311console.log("Pivot table (sum revenue by region × product):");312console.log(pivotedSum.toString());313314// ============================================================================315// Part 10: Crosstab316// ============================================================================317console.log("\n📊 Part 10: Crosstab");318console.log("-".repeat(60));319320// Crosstab computes frequency tables between two categorical columns321const survey = new DataFrame({322  gender: ["M", "F", "M", "F", "M", "F", "M", "F", "M", "F"],323  preference: ["A", "B", "A", "A", "B", "B", "A", "A", "B", "B"],324});325326console.log("Survey data:");327console.log(survey.toString());328329const crossResult = survey.crosstab("gender", "preference");330console.log("\nCrosstab (gender × preference):");331console.log(crossResult.toString());332333// ============================================================================334// Part 11: nlargest / nsmallest335// ============================================================================336console.log("\n🏆 Part 11: nlargest / nsmallest");337console.log("-".repeat(60));338339const scores = new DataFrame({340  student: ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace"],341  score: [92, 85, 78, 95, 88, 73, 91],342  grade: ["A", "B", "C", "A", "B", "C", "A"],343});344345console.log("Student scores:");346console.log(scores.toString());347348const top3 = scores.nlargest(3, "score");349console.log("\nTop 3 scores:");350console.log(top3.toString());351352const bottom3 = scores.nsmallest(3, "score");353console.log("Bottom 3 scores:");354console.log(bottom3.toString());355356// ============================================================================357// Part 12: Interpolation358// ============================================================================359console.log("\n🔗 Part 12: Interpolation");360console.log("-".repeat(60));361362// Interpolate fills missing values using linear or nearest interpolation363const sensorData = new DataFrame({364  time: [0, 1, 2, 3, 4, 5, 6, 7],365  reading: [10, null, null, 25, 30, null, 42, 50],366});367368console.log("Sensor data with gaps:");369console.log(sensorData.toString());370371const linearInterp = sensorData.interpolate("linear");372console.log("\nLinear interpolation:");373console.log(linearInterp.toString());374375const nearestInterp = sensorData.interpolate("nearest");376console.log("Nearest interpolation:");377console.log(nearestInterp.toString());378379// ============================================================================380// Summary381// ============================================================================382console.log("\n💡 Key Takeaways");383console.log("-".repeat(60));384console.log("• .str accessor: vectorized string ops (upper, lower, contains, split, etc.)");385console.log("• .dt accessor: datetime extraction (year, month, day, hour, dayofweek, quarter)");386console.log("• rolling(n): sliding window stats (mean, sum, std, var, min, max)");387console.log("• expanding(): cumulative stats from the start of the data");388console.log("• ewm({span}): exponentially weighted moving averages");389console.log("• query(): SQL-like row filtering with expressions");390console.log("• eval(): computed columns and expression-based filtering");391console.log("• assign(): functional column creation with arrays or functions");392console.log("• pivot_table(): reshape data for cross-tabulation analysis");393console.log("• crosstab(): frequency tables between categorical columns");394console.log("• nlargest/nsmallest: top/bottom N rows by column");395console.log("• interpolate(): fill missing values with linear or nearest method");396397console.log("\n✅ Advanced DataFrame Features Example Complete!");398console.log("=".repeat(60));399

Console Output

$ npx tsx 33-dataframe-advanced/index.ts
Console output demonstrating string/datetime accessors, window functions, expressions, and pivot tables