Skip to content

Commit

Permalink
loc/iloc honors fancy index order
Browse files Browse the repository at this point in the history
  • Loading branch information
John Bogaardt committed Feb 12, 2020
1 parent ac16880 commit dcc93f3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 13 deletions.
26 changes: 13 additions & 13 deletions chainladder/core/slice.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,28 @@ def get_idx(self, idx):
obj = copy.deepcopy(self.obj)
vdims = pd.Series(obj.vdims)
obj.kdims = np.array(idx.index.unique())
# Honor order of column labels
obj.vdims = np.array(vdims[vdims.isin(idx.columns.unique())])
obj.key_labels = list(idx.index.names)
obj.iloc, obj.loc = Ilocation(obj), Location(obj)
idx_slice = np.array(idx).flatten()
x = tuple([np.unique(np.array(item))
for item in list(zip(*idx_slice))])
x_0 = list(pd.Series([item[0] for item in idx.values[:, 0]]).unique())
x_1 = list(pd.Series([item[1] for item in idx.values[0, :]]).unique())
obj.values = \
obj.values[self._contig_slice(x[0])][:, self._contig_slice(x[1])]
obj.values[self._contig_slice(x_0)][:, self._contig_slice(x_1)]
obj.values[obj.values == 0] = np.nan
return obj

def _contig_slice(self, arr):
if len(arr) == 1:
return arr
sorted_arr = np.sort(arr)
diff = np.diff(sorted_arr)
if diff.max() == diff.min() == 1:
return slice(sorted_arr[0], sorted_arr[-1] + 1)
diff = np.diff(arr)
step = None if arr[0] < arr[-1] else -1
if diff.max() == diff.min() and diff.max() in [1, -1]:
# index is sorted, so use its sort for better performance
if not step:
return slice(min(arr), max(arr) + 1, step)
else:
min_arr = None if min(arr) == 0 else min(arr)
return slice(max(arr), min_arr, step)
return arr


Expand Down Expand Up @@ -103,10 +106,7 @@ def __getitem__(self, key):
obj = _LocBase(self).get_idx(idx)
if type(key) is not str and key != list(obj.vdims):
# Honor order of the slice
obj2 = obj[key[0]]
for item in key[1:]:
obj2[item] = obj[item]
return obj2
return obj.loc[:, key]
else:
return obj

Expand Down
7 changes: 7 additions & 0 deletions chainladder/core/tests/test_triangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,10 @@ def test_broadcasting():
t2 = tri
assert t1.broadcast_axis('columns', t2.columns).shape[1] == t2.shape[1]
assert t1.broadcast_axis('index', t2.index).shape[0] == t2.shape[0]

def test_slicers_honor_order():
clrd = cl.load_dataset('clrd').groupby('LOB').sum()
assert clrd.iloc[[1,0], :].iloc[0, 1] == clrd.iloc[1, 1] #row
assert clrd.iloc[[1,0], [1, 0]].iloc[0, 0] == clrd.iloc[1, 1] #col
assert clrd.loc[:,['CumPaidLoss','IncurLoss']].iloc[0, 0] == clrd.iloc[0,1]
assert clrd.loc[['ppauto', 'medmal'],['CumPaidLoss','IncurLoss']].iloc[0,0] == clrd.iloc[3]['CumPaidLoss']

0 comments on commit dcc93f3

Please sign in to comment.