Skip to content

Commit 09d45ba

Browse files
committed
implemented LArray.roll
1 parent efe7809 commit 09d45ba

File tree

3 files changed

+68
-0
lines changed

3 files changed

+68
-0
lines changed

doc/source/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ Miscellaneous
444444
LArray.divnot0
445445
LArray.clip
446446
LArray.shift
447+
LArray.roll
447448
LArray.diff
448449
LArray.to_clipboard
449450

doc/source/changes/version_0_30.rst.inc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,13 @@ New features
132132
* implemented :py:obj:`wrap_elementwise_array_func()` function to make a function defined in another library work with
133133
LArray arguments instead of with numpy arrays.
134134

135+
* implemented :py:obj:`LArray.roll()` to roll the cells of an array n-times to the right along an axis. This is similar
136+
to :py:obj:`LArray.shift()`, except that cells which are pushed "outside of the axis" are reintroduced on the opposite
137+
side of the axis instead of being dropped.
138+
135139
* implemented :py:obj:`AxisCollection.rename()` to rename axes of an AxisCollection, independently of any array.
136140

141+
137142
Miscellaneous improvements
138143
^^^^^^^^^^^^^^^^^^^^^^^^^^
139144

larray/core/array.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6853,6 +6853,11 @@ def shift(self, axis, n=1):
68536853
-------
68546854
LArray
68556855
6856+
See Also
6857+
--------
6858+
LArray.roll : cells which are pushed "outside of the axis" are reintroduced on the opposite side of the axis
6859+
instead of being dropped.
6860+
68566861
Examples
68576862
--------
68586863
>>> arr = ndtest('sex=M,F;year=2019..2021')
@@ -6877,6 +6882,63 @@ def shift(self, axis, n=1):
68776882
else:
68786883
return self[:]
68796884

6885+
def roll(self, axis=None, n=1):
6886+
r"""Rolls the cells of the array n-times to the right along axis. Cells which would be pushed "outside of the
6887+
axis" are reintroduced on the opposite side of the axis.
6888+
6889+
Parameters
6890+
----------
6891+
axis : int, str or Axis, optional
6892+
Axis along which to roll. Defaults to None (all axes).
6893+
n : int or LArray, optional
6894+
Number of positions to roll. Defaults to 1. Use a negative integers to roll left.
6895+
If n is an LArray the number of positions rolled can vary along the axes of n.
6896+
6897+
Returns
6898+
-------
6899+
LArray
6900+
6901+
See Also
6902+
--------
6903+
LArray.shift : cells which are pushed "outside of the axis" are dropped instead of being reintroduced on the
6904+
opposite side of the axis.
6905+
6906+
Examples
6907+
--------
6908+
>>> arr = ndtest('sex=M,F;year=2019..2021')
6909+
>>> arr
6910+
sex\year 2019 2020 2021
6911+
M 0 1 2
6912+
F 3 4 5
6913+
>>> arr.roll('year')
6914+
sex\year 2019 2020 2021
6915+
M 2 0 1
6916+
F 5 3 4
6917+
6918+
One can also roll by a different amount depending on another axis
6919+
6920+
>>> # let us roll by 1 for men and by 2 for women
6921+
>>> n = sequence(arr.sex, initial=1)
6922+
>>> n
6923+
sex M F
6924+
1 2
6925+
>>> arr.roll('year', n)
6926+
sex\year 2019 2020 2021
6927+
M 2 0 1
6928+
F 4 5 3
6929+
"""
6930+
if isinstance(n, (int, np.integer)):
6931+
axis_idx = None if axis is None else self.axes.index(axis)
6932+
return LArray(np.roll(self.data, n, axis=axis_idx), self.axes)
6933+
else:
6934+
if not isinstance(n, LArray):
6935+
raise TypeError("n should either be an integer or an LArray")
6936+
if axis is None:
6937+
raise TypeError("axis may not be None if n is an LArray")
6938+
axis = self.axes[axis]
6939+
seq = sequence(axis)
6940+
return self[axis.i[(seq - n) % len(axis)]]
6941+
68806942
# TODO: add support for groups as axis (like aggregates)
68816943
# eg a.diff(x.year[2018:]) instead of a[2018:].diff(x.year)
68826944
def diff(self, axis=-1, d=1, n=1, label='upper'):

0 commit comments

Comments
 (0)