1"""
2transforms.py is for shape-preserving functions.
3"""
4
5from __future__ import annotations
6
7from typing import TYPE_CHECKING
8
9import numpy as np
10
11if TYPE_CHECKING:
12 from pandas._typing import Scalar
13
14
15def shift(values: np.ndarray, periods: int, fill_value: Scalar) -> np.ndarray:
16 new_values = values
17
18 if periods == 0 or values.size == 0:
19 return new_values.copy()
20
21 # Always shift along the last axis.
22 axis = new_values.ndim - 1
23
24 # make sure array sent to np.roll is c_contiguous
25 f_ordered = values.flags.f_contiguous
26 if f_ordered:
27 new_values = new_values.T
28 axis = 0
29
30 if new_values.size:
31 new_values = np.roll(
32 new_values,
33 np.intp(periods),
34 axis=axis,
35 )
36
37 axis_indexer = [slice(None)] * values.ndim
38 if periods > 0:
39 axis_indexer[axis] = slice(None, periods)
40 else:
41 axis_indexer[axis] = slice(periods, None)
42 new_values[tuple(axis_indexer)] = fill_value
43
44 # restore original order
45 if f_ordered:
46 new_values = new_values.T
47
48 return new_values