References
Read the relevant reference before writing code — Deephaven APIs differ from similar libraries.
| Reference |
Read before code that... |
joins.md |
uses natural_join, aj, raj, exact_join, range_join |
aggregations.md |
uses agg_by, sum_by, avg_by, count_by, 20+ aggregators |
updateby.md |
uses rolling/cumulative ops, EMAs, forward fill |
time-operations.md |
parses/bins/manipulates timestamps; calendars, timezones |
kafka.md |
consumes from / produces to Kafka |
iceberg.md |
reads/writes Iceberg tables |
ui.md |
builds dashboards, components, hooks, ui.table |
plotting.md |
makes charts with dx |
csv.md |
imports/exports CSVs, always read when importing CSV |
Core Principles
- Never
print() tables and never convert to pandas just to print.
- Filter early. Put partition/grouping filters first in
where().
- In-engine over UDF. Each Python call crosses the Java boundary; prefer built-ins,
java.lang.Math, and the auto-imported query-language functions.
- Don't use pandas for intermediate steps — slow and unnecessary. Never use pandas unless specifically asked for.
- All imports at the top. No
__import__() or inline imports.
Example Table Creation
from deephaven import (
empty_table,
new_table,
ring_table,
time_table,
)
from deephaven.column import double_col, string_col
# Empty table with formulas
t = empty_table(100).update(["X = i", "Y = X * 2"])
# New table from columns
t = new_table(
[string_col("Sym", ["AAPL", "GOOG"]), double_col("Price", [150.0, 140.0])]
)
# Ticking time table (real-time); accepts duration strings
t = time_table("PT1s")
# Ring table — bounded size, keeps last N rows
source = time_table("PT1s")
t = ring_table(source, capacity=1000)
Extracting Scalar Values
print(table) only shows the object reference. To get actual cell values from a 1-row table, drop to the Java backing: table.j_table.getColumnSource("Col").get(table.j_table.getRowSet().firstRowKey()).
Column Operations
from deephaven import empty_table
t = empty_table(100).update(["A = i", "B = i * 2", "OldName = i", "Unwanted = i"])
# only named cols, results in RAM.
# Best for: subset with expensive formula or frequent access.
t.select(["A", "B", "C = A + B"])
# only named cols, recomputed on access (no RAM).
# Best for: subset with cheap formula, sparse access, or memory pressure.
t.view(["A", "B", "C = A + B"])
# all cols + new, results in RAM.
# Best for: results that feed downstream ops (joins, aggs, further updates).
t.update(["C = A + B", "D = sqrt(C)"])
# all cols + new, recomputed on access.
# Best for: display-only columns, or when memory is a concern.
t.update_view(["C = A + B"])
# all cols + new, memoized by input value.
# Best for: few distinct inputs relative to row count (e.g. category lookups).
t.lazy_update(["C = A + B"])
t.drop_columns(["Unwanted"])
t.select_distinct(["A"]) # unique; multi-col → unique tuples
t.rename_columns(["NewName = OldName"])
Filtering
from deephaven import empty_table, new_table
from deephaven.column import string_col
t = empty_table(4).update(
[
"Sym = i % 2 == 0 ? `AAPL` : `GOOG`",
"Price = 50.0 + i * 50.0",
"Timestamp = parseInstant(`2024-06-01T00:00:00 UTC`) + i * 'P1d'",
]
)
filter_table = new_table([string_col("Sym", ["AAPL"])])
t.where("Price > 100")
t.where(["Sym = `AAPL`", "Price > 100"]) # list = AND
t.where("Sym.startsWith(`A`)") # Java String methods
t.where("Sym in `AAPL`, `GOOG`") # set membership (fast)
t.where_in(filter_table, "Sym") # / where_not_in
t.where("Timestamp > parseInstant(`2024-01-01T00:00:00 America/New_York`)")
sym = "AAPL" # dynamic — backtick the value
t.where(f"Sym = `{sym}`")
Joins Overview
Read references/joins.md before using joins.
- Exact match:
natural_join (add cols from right; NULL if no match), exact_join (errors unless exactly one match), join (all matching combinations).
- Time-series:
aj (closest ≤ timestamp), raj (closest ≥ timestamp).
- Range:
range_join — match within a range, aggregate results.
- Vertical stack:
from deephaven import merge; merge([t1, t2]) (column names and types must match).
Aggregations Overview
Read references/aggregations.md before using aggregations.
- Single stat, all numeric cols:
sum_by, avg_by, min_by, max_by, median_by, std_by, var_by, abs_sum_by — e.g. t.sum_by("Sym").
count_by("Count", "Sym") — row count per group (first arg is output col name).
first_by / last_by, head_by(N, ...) / tail_by(N, ...) — first/last row(s) per group.
weighted_avg_by / weighted_sum_by — first arg is the weight col.
agg_by([...], by=[...]) — multiple aggs in one pass (agg.avg(...), agg.sum_(...), …).
group_by / ungroup — collect into arrays / explode back. partition_by — split into sub-tables.
Dedicated aggs operate on ALL non-key columns and throw UnsupportedOperationException on String/Timestamp. Fix: .view() to keep only key + numeric first, or use agg_by with explicit cols.
Query String Syntax
Literals: Boolean true/false (lowercase). Int 42, Long 42L, Double 3.14 (no 1_000L underscores). Bare integers in / produce doubles — (year / 10) * 10 → 1987.0; fix with year - year % 10 or (int)(year / 10) * 10. String: backticks. DateTime: parseInstant(\2024-01-01T12:00:00 America/New_York`)— short aliases likeNYdo NOT work. Duration'PT1h30m'. Period 'P1y2m3d'`.
Built-ins: i row index (0-based); ii or k row key (stable).
from deephaven import empty_table
# Ternary + null handling
t = empty_table(10).update(
[
"Price = i * 25.0",
"Category = Price > 100 ? `High` : `Low`",
"Value = i % 2 == 0 ? NULL_INT : i",
"Safe = isNull(Value) ? 0 : Value",
]
)
Data Import/Export
from deephaven import empty_table, read_csv, write_csv
from deephaven.parquet import read, write
t = empty_table(10).update(["X = i", "Y = X * 2"])
write_csv(t, "/tmp/o.csv")
t_csv = read_csv("/tmp/o.csv")
write(t, "/tmp/o.parquet")
t_pq = read("/tmp/o.parquet")
1---2name: deephaven-core-query-writing3description: Work with Deephaven for real-time data processing. Use for table queries, joins, aggregations, time-series, UI dashboards, plotting (dx), Kafka streaming, Iceberg integration. Triggers on mentions of Deephaven, tables or queries, and related concepts.4license: Apache-2.05---67## References89Read the relevant reference before writing code — Deephaven APIs differ from similar libraries.1011| Reference | Read before code that... |12| --- | --- |13| `joins.md` | uses `natural_join`, `aj`, `raj`, `exact_join`, `range_join` |14| `aggregations.md` | uses `agg_by`, `sum_by`, `avg_by`, `count_by`, 20+ aggregators |15| `updateby.md` | uses rolling/cumulative ops, EMAs, forward fill |16| `time-operations.md` | parses/bins/manipulates timestamps; calendars, timezones |17| `kafka.md` | consumes from / produces to Kafka |18| `iceberg.md` | reads/writes Iceberg tables |19| `ui.md` | builds dashboards, components, hooks, `ui.table` |20| `plotting.md` | makes charts with `dx` |21| `csv.md` | imports/exports CSVs, always read when importing CSV |2223## Core Principles2425- **Never `print()` tables and never convert to pandas just to print.**26- **Filter early.** Put partition/grouping filters first in `where()`.27- **In-engine over UDF.** Each Python call crosses the Java boundary; prefer built-ins, `java.lang.Math`, and the auto-imported query-language functions.28- **Don't use pandas for intermediate steps** — slow and unnecessary. Never use pandas unless specifically asked for.29- **All imports at the top.** No `__import__()` or inline imports.3031### Example Table Creation3233```python34from deephaven import (35 empty_table,36 new_table,37 ring_table,38 time_table,39)40from deephaven.column import double_col, string_col4142# Empty table with formulas43t = empty_table(100).update(["X = i", "Y = X * 2"])4445# New table from columns46t = new_table(47 [string_col("Sym", ["AAPL", "GOOG"]), double_col("Price", [150.0, 140.0])]48)4950# Ticking time table (real-time); accepts duration strings51t = time_table("PT1s")5253# Ring table — bounded size, keeps last N rows54source = time_table("PT1s")55t = ring_table(source, capacity=1000)56```5758### Extracting Scalar Values5960`print(table)` only shows the object reference. To get actual cell values from a 1-row table, drop to the Java backing: `table.j_table.getColumnSource("Col").get(table.j_table.getRowSet().firstRowKey())`.6162### Column Operations6364```python65from deephaven import empty_table6667t = empty_table(100).update(["A = i", "B = i * 2", "OldName = i", "Unwanted = i"])6869# only named cols, results in RAM.70# Best for: subset with expensive formula or frequent access.71t.select(["A", "B", "C = A + B"])7273# only named cols, recomputed on access (no RAM).74# Best for: subset with cheap formula, sparse access, or memory pressure.75t.view(["A", "B", "C = A + B"])7677# all cols + new, results in RAM.78# Best for: results that feed downstream ops (joins, aggs, further updates).79t.update(["C = A + B", "D = sqrt(C)"])8081# all cols + new, recomputed on access.82# Best for: display-only columns, or when memory is a concern.83t.update_view(["C = A + B"])8485# all cols + new, memoized by input value.86# Best for: few distinct inputs relative to row count (e.g. category lookups).87t.lazy_update(["C = A + B"])8889t.drop_columns(["Unwanted"])90t.select_distinct(["A"]) # unique; multi-col → unique tuples91t.rename_columns(["NewName = OldName"])92```9394### Filtering9596```python97from deephaven import empty_table, new_table98from deephaven.column import string_col99100t = empty_table(4).update(101 [102 "Sym = i % 2 == 0 ? `AAPL` : `GOOG`",103 "Price = 50.0 + i * 50.0",104 "Timestamp = parseInstant(`2024-06-01T00:00:00 UTC`) + i * 'P1d'",105 ]106)107filter_table = new_table([string_col("Sym", ["AAPL"])])108109t.where("Price > 100")110t.where(["Sym = `AAPL`", "Price > 100"]) # list = AND111t.where("Sym.startsWith(`A`)") # Java String methods112t.where("Sym in `AAPL`, `GOOG`") # set membership (fast)113t.where_in(filter_table, "Sym") # / where_not_in114t.where("Timestamp > parseInstant(`2024-01-01T00:00:00 America/New_York`)")115116sym = "AAPL" # dynamic — backtick the value117t.where(f"Sym = `{sym}`")118```119120### Joins Overview121122**Read `references/joins.md` before using joins.**123124- **Exact match:** `natural_join` (add cols from right; NULL if no match), `exact_join` (errors unless exactly one match), `join` (all matching combinations).125- **Time-series:** `aj` (closest ≤ timestamp), `raj` (closest ≥ timestamp).126- **Range:** `range_join` — match within a range, aggregate results.127- **Vertical stack:** `from deephaven import merge`; `merge([t1, t2])` (column names and types must match).128129### Aggregations Overview130131**Read `references/aggregations.md` before using aggregations.**132133- **Single stat, all numeric cols:** `sum_by`, `avg_by`, `min_by`, `max_by`, `median_by`, `std_by`, `var_by`, `abs_sum_by` — e.g. `t.sum_by("Sym")`.134- **`count_by("Count", "Sym")`** — row count per group (first arg is output col name).135- **`first_by` / `last_by`**, **`head_by(N, ...)` / `tail_by(N, ...)`** — first/last row(s) per group.136- **`weighted_avg_by` / `weighted_sum_by`** — first arg is the weight col.137- **`agg_by([...], by=[...])`** — multiple aggs in one pass (`agg.avg(...)`, `agg.sum_(...)`, …).138- **`group_by` / `ungroup`** — collect into arrays / explode back. **`partition_by`** — split into sub-tables.139140Dedicated aggs operate on ALL non-key columns and throw `UnsupportedOperationException` on String/Timestamp. **Fix:** `.view()` to keep only key + numeric first, or use `agg_by` with explicit `cols`.141142### Query String Syntax143144**Literals:** Boolean `true`/`false` (lowercase). Int `42`, Long `42L`, Double `3.14` (no `1_000L` underscores). **Bare integers in `/` produce doubles** — `(year / 10) * 10` → `1987.0`; fix with `year - year % 10` or `(int)(year / 10) * 10`. String: backticks. DateTime: `parseInstant(\`2024-01-01T12:00:00 America/New_York\`)` — short aliases like `NY` do NOT work. Duration `'PT1h30m'`. Period `'P1y2m3d'`.145146**Built-ins:** `i` row index (0-based); `ii` or `k` row key (stable).147148```python149from deephaven import empty_table150151# Ternary + null handling152t = empty_table(10).update(153 [154 "Price = i * 25.0",155 "Category = Price > 100 ? `High` : `Low`",156 "Value = i % 2 == 0 ? NULL_INT : i",157 "Safe = isNull(Value) ? 0 : Value",158 ]159)160```161162### Data Import/Export163164```python165from deephaven import empty_table, read_csv, write_csv166from deephaven.parquet import read, write167168t = empty_table(10).update(["X = i", "Y = X * 2"])169write_csv(t, "/tmp/o.csv")170t_csv = read_csv("/tmp/o.csv")171write(t, "/tmp/o.parquet")172t_pq = read("/tmp/o.parquet")173```