atoti.measures.Measures#

final class atoti.measures.Measures#

Manage the Measure of a Cube.

The built-in measure contributors.COUNT counts how many rows from the cube’s fact table contributed to each aggregate of a query:

Example

>>> df = pd.DataFrame(
...     columns=["ID", "Continent", "Country", "City", "Color"],
...     data=[
...         (1, "Asia", "Japan", "Tokyo", "red"),
...         (2, "Asia", "Japan", "Kyoto", "red"),
...         (3, "Asia", "Singapore", "Singapore", "white"),
...         (4, "Europe", "Spain", "Madrid", "green"),
...         (5, "Europe", "Spain", "Barcelona", "blue"),
...     ],
... )
>>> table = session.read_pandas(df, keys={"ID"}, table_name="Cities")
>>> cube = session.create_cube(table, mode="manual")
>>> h, l, m = cube.hierarchies, cube.levels, cube.measures
>>> h["ID"] = [table["ID"]]
>>> cube.query(m["contributors.COUNT"])
  contributors.COUNT
0                  5
>>> cube.query(m["contributors.COUNT"], levels=[l["ID"]], include_totals=True)
      contributors.COUNT
ID
Total                  5
1                      1
2                      1
3                      1
4                      1
5                      1

The caption of this measure can be changed with I18nConfig.

A measure can evaluate to the current member of an expressed level:

>>> h["Color"] = [table["Color"]]
>>> m["Color"] = l["Color"]
>>> cube.query(
...     m["Color"],
...     m["contributors.COUNT"],
...     levels=[l["Color"]],
...     include_totals=True,
... )
       Color contributors.COUNT
Color
Total                         5
blue    blue                  1
green  green                  1
red      red                  2
white  white                  1

Or, for a multilevel hierarchy:

>>> h["Geography"] = [table["Continent"], table["Country"], table["City"]]
>>> m["Geography"] = h["Geography"]
>>> cube.query(
...     m["Geography"],
...     m["contributors.COUNT"],
...     levels=[l["City"]],
...     include_totals=True,
... )
                               Geography contributors.COUNT
Continent Country   City
Total                                                     5
Asia                                Asia                  3
          Japan                    Japan                  2
                    Kyoto          Kyoto                  1
                    Tokyo          Tokyo                  1
          Singapore            Singapore                  1
                    Singapore  Singapore                  1
Europe                            Europe                  2
          Spain                    Spain                  2
                    Barcelona  Barcelona                  1
                    Madrid        Madrid                  1

A measure can be compared to other objects, such as a constant, a Level, or another measure. If some condition inputs evaluate to None, the resulting measure will evaluate to False:

>>> df = pd.DataFrame(
...     columns=["Product", "Quantity", "Threshold"],
...     data=[
...         ("bag", 5, 1),
...         ("car", 1, 5),
...         ("laptop", 4, None),
...         ("phone", None, 2),
...         ("watch", 3, 3),
...     ],
... )
>>> table = session.read_pandas(df, keys={"Product"}, table_name="Products")
>>> cube = session.create_cube(table)
>>> l, m = cube.levels, cube.measures
>>> m["Condition"] = m["Quantity.SUM"] > m["Threshold.SUM"]
>>> cube.query(
...     m["Quantity.SUM"],
...     m["Threshold.SUM"],
...     m["Condition"],
...     levels=[l["Product"]],
...     include_totals=True,
... )
        Quantity.SUM Threshold.SUM Condition
Product
Total          13.00         11.00      True
bag             5.00          1.00      True
car             1.00          5.00     False
laptop          4.00                   False
phone                         2.00     False
watch           3.00          3.00     False

Measures can be defined and redefined without restarting the cube but, at the moment, deleting a measure will restart the cube so it will be slower:

>>> m["test"] = 13  # no cube restart
>>> m["test"] = 42  # no cube restart
>>> del m["test"]  # cube restart

See also