atoti.date_shift()#
- atoti.date_shift(measure: VariableMeasureConvertible, on: Hierarchy, /, *, offset: str, dense: bool = False, fallback: Literal['past', 'interpolated', 'future'] | None = None) MeasureDefinition #
- atoti.date_shift(measure: VariableMeasureConvertible, on: Hierarchy, /, *, offset: str, method: Literal['exact', 'previous', 'next', 'interpolate', 'dense'] = 'exact') MeasureDefinition
Return a measure equal to the passed measure shifted to another date.
- Parameters:
measure – The measure to shift.
on – The hierarchy to shift on. Only hierarchies with their last level with a
data_type
of"LocalDate"
or"LocalDateTime"
are supported.offset – The period to shift by as specified by Java’s Period.parse().
dense –
If
False
, the returned measure will evaluate toNone
everywhere the input measure evaluates toNone
.If
True
, the returned measure will be evaluated on all the queried members of the on hierarchy, even if the input measure evaluates toNone
there.In any case, facts are never “created”: if measure evaluates to a non-
None
value on 2025-01-01 andoffset="-P2D"
but 2025-01-03 is not a member of the on hierarchy, 2025-01-03 will remain absent from the query results.fallback –
The value to use if measure evaluates to
None
at the shifted location:None
: No value.past
: Value at the previous date in chronological order.interpolated
: Linear interpolation of the values at the past and future existing dates orNone
if either date is missing.future
: Value at the next date in chronological order.
Example
>>> from datetime import date >>> df = pd.DataFrame( ... columns=["Date", "Price"], ... data=[ ... (date(2020, 8, 1), 5), ... (date(2020, 8, 15), 7), ... (date(2020, 8, 30), 15), ... (date(2020, 8, 31), 15), ... (date(2020, 9, 1), 10), ... (date(2020, 9, 30), 21), ... (date(2020, 10, 1), 9), ... (date(2020, 10, 31), 8), ... ], ... ) >>> table = session.read_pandas( ... df, keys={"Date"}, table_name="Fallback example" ... ) >>> cube = session.create_cube(table) >>> h, l, m = cube.hierarchies, cube.levels, cube.measures >>> cube.create_date_hierarchy( ... "Date parts", ... column=table["Date"], ... levels={"Year": "y", "Month": "M"}, ... ) >>> h["Date"] = {**h["Date parts"], "Date": table["Date"]} >>> m["Exact (+)"] = tt.date_shift(m["Price.SUM"], h["Date"], offset="P1M") >>> m["Exact (-)"] = tt.date_shift(m["Price.SUM"], h["Date"], offset="-P1M") >>> m["Past"] = tt.date_shift( ... m["Price.SUM"], h["Date"], offset="P1M", fallback="past" ... ) >>> m["Interpolated"] = tt.date_shift( ... m["Price.SUM"], h["Date"], offset="P1M", fallback="interpolated" ... ) >>> m["Future"] = tt.date_shift( ... m["Price.SUM"], h["Date"], offset="P1M", fallback="future" ... ) >>> cube.query( ... m["Price.SUM"], ... m["Exact (+)"], ... m["Exact (-)"], ... m["Past"], ... m["Interpolated"], ... m["Future"], ... levels=[l["Date"]], ... include_totals=True, ... ) Price.SUM Exact (+) Exact (-) Past Interpolated Future Year Month Date Total 90 2020 90 8 42 2020-08-01 5 10 10 10.00 10 2020-08-15 7 10 15.31 21 2020-08-30 15 21 21 21.00 21 2020-08-31 15 21 21 21.00 21 9 31 2020-09-01 10 9 5 9 9.00 9 2020-09-30 21 15 9 8.03 8 10 17 2020-10-01 9 10 8 2020-10-31 8 21 8
Explanations:
“Exact (+):
The value for 2020-08-31 is taken from 2020-09-30 even though
31 != 30
because there are both the last day of their respective month.
“Exact (-):
The value for 2020-10-31 is taken from 2020-09-30 for the same reason.
Interpolated:
10.00, 21.00, 21.00, and 9.00: no interpolation required since there is an exact match.
15.31: linear interpolation of 2020-09-01’s 10 and 2020-09-30’s 21 at 2020-09-15.
8.03: linear interpolation of 2020-10-01’s 9 and 2020-10-31’s 8 at 2020-10-30.
∅: no interpolation possible because there are no records after
2020-10-31
.
Behavior of the dense parameter:
>>> df = pd.DataFrame( ... columns=["Date", "City", "Price"], ... data=[ ... (date(2020, 8, 1), "London", 10), ... (date(2020, 8, 1), "New York", 12), ... (date(2020, 9, 1), "New York", 15), ... (date(2020, 10, 1), "London", 18), ... (date(2020, 10, 1), "New York", 20), ... ], ... ) >>> table = session.read_pandas( ... df, keys={"Date", "City"}, table_name="Dense example" ... ) >>> cube = session.create_cube(table) >>> h, l, m = cube.hierarchies, cube.levels, cube.measures >>> cube.create_date_hierarchy( ... "Date parts", column=table["Date"], levels={"Year": "y", "Month": "M"} ... ) >>> h["Date"] = {**h["Date parts"], "Date": table["Date"]} >>> m["Sparse"] = tt.date_shift( ... m["Price.SUM"], h["Date"], offset="P1M", dense=False ... ) >>> m["Dense"] = tt.date_shift( ... m["Price.SUM"], h["Date"], offset="P1M", dense=True ... ) >>> cube.query( ... m["Price.SUM"], m["Sparse"], m["Dense"], levels=[l["Date"], l["City"]] ... ) Price.SUM Sparse Dense Year Month Date City 2020 8 2020-08-01 London 10 New York 12 15 15 9 2020-09-01 London 18 New York 15 20 20 10 2020-10-01 London 18 New York 20
Explanations:
Sparse:
There is no value for (2020-09-01, London) because, although both members exist separately, no fact contains both simultaneously.
Dense:
The value for (2020-09-01, London) is taken from (2020-10-01, London).
There are no values for 2020-10-01 because 2020-11-01 is not a member of the Date hierarchy.