← tsb playground
DataFrame.query() and DataFrame.eval()
queryDataFrame and evalDataFrame let you filter rows or evaluate
expressions using a Python-pandas-style expression string. This mirrors
pandas.DataFrame.query()
and
pandas.DataFrame.eval().
Import
import { queryDataFrame, evalDataFrame, DataFrame } from "tsb";
queryDataFrame(df, expr)
Returns a new DataFrame containing only the rows where expr evaluates to truthy.
const df = DataFrame.fromArrays({
name: ["Alice", "Bob", "Carol", "Dave"],
age: [25, 32, 28, 45],
score: [88, 72, 95, 60],
active: [true, false, true, true],
});
// Simple comparison
queryDataFrame(df, "age > 28");
// name: ["Bob", "Dave"] age: [32, 45] score: [72, 60]
// Combined conditions
queryDataFrame(df, "age < 35 and score >= 85");
// name: ["Alice", "Carol"]
// String equality
queryDataFrame(df, "name == 'Alice'");
// single row
// 'in' operator
queryDataFrame(df, "name in ['Alice', 'Carol']");
// 'not in' operator
queryDataFrame(df, "age not in [25, 45]");
// Backtick-quoted column (for names with spaces)
const df2 = DataFrame.fromArrays({ "first name": ["Alice", "Bob"] });
queryDataFrame(df2, "`first name` == 'Alice'");
evalDataFrame(df, expr)
Evaluates an arithmetic or logical expression and returns a new Series.
const sales = DataFrame.fromArrays({
price: [10.0, 25.0, 5.0, 40.0],
qty: [100, 50, 200, 10],
});
// Arithmetic expression → new Series
evalDataFrame(sales, "price * qty");
// Series [1000, 1250, 1000, 400]
// Boolean expression (useful as a mask)
evalDataFrame(sales, "price > 10");
// Series [false, true, false, true]
// Function calls
evalDataFrame(sales, "round(price * qty / 100, 1)");
// Series [10.0, 12.5, 10.0, 4.0]
// String operations
const df3 = DataFrame.fromArrays({ tag: ["Foo", "Bar", "Baz"] });
evalDataFrame(df3, "lower(tag)");
// Series ["foo", "bar", "baz"]
Supported Expression Syntax
Column references
| Syntax | Example |
| Bare identifier | age |
| Backtick-quoted (spaces allowed) | `first name` |
Literals
| Type | Examples |
| Number | 42, 3.14, 1e6 |
| String | "hello", 'world' |
| Boolean | True, False, true, false |
| Null | None, null, NaN |
Operators
| Category | Operators |
| Arithmetic | + - * / % ** |
| Comparison | == != < <= > >= |
| Logical | and or not |
| Membership | in [...], not in [...] |
Built-in functions
| Function | Description |
abs(x) | Absolute value |
round(x, d?) | Round to d decimal places (default 0) |
floor(x), ceil(x) | Floor / ceiling |
sqrt(x), log(x), log2(x), log10(x) | Math functions |
str(x), len(x) | Convert to string / string length |
lower(x), upper(x) | String case conversion |
isnull(x) / isna(x) | True if null / NaN |
notnull(x) / notna(x) | True if not null |
Pandas API comparison
| pandas | tsb |
df.query("col > 5") | queryDataFrame(df, "col > 5") |
df.eval("a + b") | evalDataFrame(df, "a + b") |
df.query("col in [1,2,3]") | queryDataFrame(df, "col in [1, 2, 3]") |
df.query("`col name` == 'x'") | queryDataFrame(df, "`col name` == 'x'") |
df.eval("func(col)") | evalDataFrame(df, "abs(col)") (built-in functions) |
Note: Unlike pandas, external variable substitution (@var) is not supported.
Use template literals to embed values: queryDataFrame(df, `age > ${minAge}`).
Tips
- Operator precedence follows Python/math conventions:
** > unary - > * / % > + - > comparisons > not > and > or.
and/or short-circuit: false and f() won't evaluate f().
- Null propagation: arithmetic/comparison on null yields null (treated as falsy in logical ops).
- For null checks, prefer
isnull(col) over col == None.