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