atoti.measure module#

class atoti.Measure#

A measure is a mostly-numeric data value, computed on demand for aggregation purposes.

Measures can be compared to other objects, such as a constant, a atoti.Level, or another measure. The returned measure represents the outcome of the comparison and this measure can be used as a condition. If the measure’s value is None when evaluating a condition, the returned value will be False.

Example

>>> df = pd.DataFrame(
...     columns=["Id", "Value", "Threshold"],
...     data=[
...         (0, 1.0, 5.0),
...         (1, 2.0, None),
...         (2, 3.0, 3.0),
...         (3, 4.0, None),
...         (4, 5.0, 1.0),
...     ],
... )
>>> table = session.read_pandas(df, keys=["Id"], table_name="Measure example")
>>> cube = session.create_cube(table)
>>> l, m = cube.levels, cube.measures
>>> m["Condition"] = m["Value.SUM"] > m["Threshold.SUM"]
>>> cube.query(m["Condition"], levels=[l["Id"]])
   Condition
Id
0      False
1      False
2      False
3      False
4       True
property data_type: Literal['boolean', 'double', 'double[]', 'float', 'float[]', 'int', 'int[]', 'LocalDate', 'LocalDateTime', 'LocalTime', 'long', 'long[]', 'Object', 'Object[]', 'String', 'ZonedDateTime']#

Type of the measure members.

Return type

Literal[‘boolean’, ‘double’, ‘double[]’, ‘float’, ‘float[]’, ‘int’, ‘int[]’, ‘LocalDate’, ‘LocalDateTime’, ‘LocalTime’, ‘long’, ‘long[]’, ‘Object’, ‘Object[]’, ‘String’, ‘ZonedDateTime’]

property description: Optional[str]#

Description of the measure.

Example

>>> df = pd.DataFrame(
...     columns=["Product", "Price"],
...     data=[
...         ("phone", 560),
...         ("headset", 80),
...         ("watch", 250),
...     ],
... )
>>> table = session.read_pandas(
...     df, keys=["Product"], table_name="Description example"
... )
>>> cube = session.create_cube(table)
>>> m = cube.measures
>>> print(m["Price.SUM"].description)
None
>>> m["Price.SUM"].description = "The sum of the price"
>>> m["Price.SUM"].description
'The sum of the price'
>>> del m["Price.SUM"].description
>>> print(m["Price.SUM"].description)
None
Return type

Optional[str]

property folder: Optional[str]#

Folder of the measure.

Folders can be used to group measures in the Data model UI component.

Example

>>> df = pd.DataFrame(
...     columns=["Product", "Price"],
...     data=[
...         ("phone", 600.0),
...         ("headset", 80.0),
...         ("watch", 250.0),
...     ],
... )
>>> table = session.read_pandas(
...     df, keys=["Product"], table_name="Folder example"
... )
>>> cube = session.create_cube(table)
>>> m = cube.measures
>>> print(m["Price.SUM"].folder)
None
>>> m["Price.SUM"].folder = "Prices"
>>> m["Price.SUM"].folder
'Prices'
>>> del m["Price.SUM"].folder
>>> print(m["Price.SUM"].folder)
None
Return type

Optional[str]

property formatter: Optional[str]#

Formatter of the measure.

Note

The formatter only impacts how the measure is displayed, derived measures will still be computed from unformatted value. To round a measure, use atoti.math.round() instead.

Example

>>> df = pd.DataFrame(
...     columns=["Product", "Price", "Quantity"],
...     data=[
...         ("phone", 559.99, 2),
...         ("headset", 79.99, 4),
...         ("watch", 249.99, 3),
...     ],
... )
>>> table = session.read_pandas(
...     df, keys=["Product"], table_name="Formatter example"
... )
>>> cube = session.create_cube(table)
>>> h, l, m = cube.hierarchies, cube.levels, cube.measures
>>> m["contributors.COUNT"].formatter
'INT[#,###]'
>>> m["contributors.COUNT"].formatter = "INT[count: #,###]"
...
>>> m["contributors.COUNT"].formatter
'INT[count: #,###]'
>>> m["Price.SUM"].formatter
'DOUBLE[#,###.00]'
>>> m["Price.SUM"].formatter = "DOUBLE[$#,##0.00]"  # Add $ symbol
>>> m["Ratio of sales"] = m["Price.SUM"] / tt.total(
...     m["Price.SUM"], h["Product"]
... )
>>> m["Ratio of sales"].formatter
'DOUBLE[#,###.00]'
>>> m["Ratio of sales"].formatter = "DOUBLE[0.00%]"  # Percentage
>>> m["Turnover in dollars"] = tt.agg.sum(
...     table["Price"] * table["Quantity"],
... )
>>> m["Turnover in dollars"].formatter
'DOUBLE[#,###.00]'
>>> m["Turnover in dollars"].formatter = "DOUBLE[#,###]"  # Without decimals
>>> cube.query(
...     m["contributors.COUNT"],
...     m["Price.SUM"],
...     m["Ratio of sales"],
...     m["Turnover in dollars"],
...     levels=[l["Product"]],
... )
        contributors.COUNT Price.SUM Ratio of sales Turnover in dollars
Product
headset           count: 1    $79.99          8.99%                 320
phone             count: 1   $559.99         62.92%               1,120
watch             count: 1   $249.99         28.09%                 750

The spec for the pattern between the DATE or DOUBLE’s brackets is the one from Microsoft Analysis Services.

There is an extra formatter for array measures: ARRAY['|';1:3] where | is the separator used to join the elements of the 1:3 slice.

Return type

Optional[str]

isnull()#

Return a measure evaluating to True if the measure is None and False otherwise.

Use ~measure.isnull() for the opposite behavior.

Example

>>> df = pd.DataFrame(
...     columns=["Country", "City", "Price"],
...     data=[
...         ("France", "Paris", 200.0),
...         ("Germany", "Berlin", None),
...     ],
... )
>>> table = session.read_pandas(df, table_name="isnull example")
>>> cube = session.create_cube(table)
>>> l, m = cube.levels, cube.measures
>>> m["Price.isnull"] = m["Price.SUM"].isnull()
>>> m["Price.notnull"] = ~m["Price.SUM"].isnull()
>>> cube.query(
...     m["Price.isnull"],
...     m["Price.notnull"],
...     levels=[l["Country"]],
... )
        Price.isnull Price.notnull
Country
France         False          True
Germany         True         False
property name: str#

Name of the measure.

Return type

str

property visible: bool#

Whether the measure is visible or not.

Example

>>> df = pd.DataFrame(
...     columns=["Product", "Price"],
...     data=[
...         ("phone", 560),
...         ("headset", 80),
...         ("watch", 250),
...     ],
... )
>>> table = session.read_pandas(
...     df, keys=["Product"], table_name="Visible example"
... )
>>> cube = session.create_cube(table)
>>> m = cube.measures
>>> m["Price.SUM"].visible
True
>>> m["Price.SUM"].visible = False
>>> m["Price.SUM"].visible
False
>>> m["contributors.COUNT"].visible
True
>>> m["contributors.COUNT"].visible = False
>>> m["contributors.COUNT"].visible
False
Return type

bool