Skip to main content
GuideServerConfigure and deploy Tabsdata servers on your machine.TutorialsConfigure data integration workflows within a running Tabsdata server.Advanced TutorialsBuild end-to-end workflows between two specific systems.API ReferenceCLI ReferenceRelease Notes
Version: 2.0.2

Transform Numbers

Arithmetic​

AI agent session
make a new table that takes the orders table and adds 10 to the price column

Needs a transformer. Getting its guide.

Called tabsdata 2 times (ctrl+o to expand)

Generating — the + operator works directly on a column expression, so no method call is needed. add() is the method form and does the same thing.

Called tabsdata 3 times (ctrl+o to expand)

The transformer, registered in subscriptions:

@transformer(
input_tables=["orders"],
output_tables=["orders_bumped"],
)
def bump_price(orders: TableFrameSpec) -> TableFrameSpec:
expr = col("price") + 10
return orders.with_columns(expr)

Execution committed, 0 failures.

subscriptions/orders_bumped is live — 10 added to every price:

┌───────┐
│ price │
├───────┤
│ 110   │
├───────┤
│ 50    │
└───────┘

Transformed tables

orders
price
100
40
2 rows
orders_bumped
price
110
50
2 rows

Round and clip​

AI agent session
make a new table that takes the items table and rounds the price column to 2 decimal places

Needs a transformer. Getting its guide.

Called tabsdata 2 times (ctrl+o to expand)

Generating — round(2) rounds to that many decimal places.

Called tabsdata 3 times (ctrl+o to expand)

The transformer, registered in subscriptions:

@transformer(
input_tables=["items"],
output_tables=["items_rounded"],
)
def round_price(items: TableFrameSpec) -> TableFrameSpec:
expr = col("price").round(2) # Round to 2 decimal places
return items.with_columns(expr)

Execution committed, 0 failures.

subscriptions/items_rounded is live — price to 2 decimal places:

┌────────┬───────┐
│  item  │ price │
├────────┼───────┤
│ widget │ 19.99 │
├────────┼───────┤
│ gadget │ 4.2   │
└────────┴───────┘

Transformed tables

items
itemprice
widget19.9876
gadget4.201
2 rows
items_rounded
itemprice
widget19.99
gadget4.2
2 rows

Powers, roots and logs​

AI agent session
make a new table that takes the readings table and takes the absolute value of the change column

Needs a transformer. Getting its guide.

Called tabsdata 2 times (ctrl+o to expand)

Generating — abs() drops the sign.

Called tabsdata 3 times (ctrl+o to expand)

The transformer, registered in subscriptions:

@transformer(
input_tables=["readings"],
output_tables=["readings_absolute"],
)
def abs_change(readings: TableFrameSpec) -> TableFrameSpec:
expr = col("change").abs()
return readings.with_columns(expr)

Execution committed, 0 failures.

subscriptions/readings_absolute is live — the sign dropped:

┌────────┐
│ change │
├────────┤
│ 4.5    │
├────────┤
│ 2      │
└────────┘

Transformed tables

readings
change
-4.5
2
2 rows
readings_absolute
change
4.5
2
2 rows

Trigonometry​

AI agent session
make a new table that takes the readings table and takes the sine of the angle column

Needs a transformer. Getting its guide.

Called tabsdata 2 times (ctrl+o to expand)

Generating — sin(). The input is read in radians, so use radians() first if the column holds degrees.

Called tabsdata 3 times (ctrl+o to expand)

The transformer, registered in subscriptions:

@transformer(
input_tables=["readings"],
output_tables=["readings_sine"],
)
def sin_angle(readings: TableFrameSpec) -> TableFrameSpec:
expr = col("angle").sin()
return readings.with_columns(expr)

Execution committed, 0 failures.

subscriptions/readings_sine is live — the sine of each angle:

┌────────┐
│ angle  │
├────────┤
│ 0      │
├────────┤
│ 0.8415 │
└────────┘

Transformed tables

readings
angle
0
1
2 rows
readings_sine
angle
0
0.8415
2 rows

Compare with earlier rows​

AI agent session
make a new table that takes the readings table and takes the change in the value column from the previous row

Needs a transformer. Getting its guide.

Called tabsdata 2 times (ctrl+o to expand)

Generating — diff() compares each row with the one before it, so the first row has no predecessor and comes out null. It reads the table in its current order.

Called tabsdata 3 times (ctrl+o to expand)

The transformer, registered in subscriptions:

@transformer(
input_tables=["readings"],
output_tables=["readings_delta"],
)
def row_delta(readings: TableFrameSpec) -> TableFrameSpec:
expr = col("value").diff() # Difference from previous row
return readings.with_columns(expr)

Execution committed, 0 failures.

subscriptions/readings_delta is live — the change from the previous row, null on the first:

┌───────┐
│ value │
├───────┤
│ null  │
├───────┤
│ 3     │
├───────┤
│ -4    │
└───────┘

Transformed tables

readings
value
10
13
9
3 rows
readings_delta
value
null
3
-4
3 rows