Skip to content

Commit 0a1021a

Browse files
[178390751]: address comments 3part
1 parent 2312469 commit 0a1021a

File tree

4 files changed

+255
-215
lines changed

4 files changed

+255
-215
lines changed

src/cr/cube/matrix/assembler.py

Lines changed: 64 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -251,32 +251,28 @@ def means(self):
251251
@lazyproperty
252252
def pairwise_indices(self):
253253
"""2D ndarray of tuple of int column-idxs pairwise-t threshold."""
254-
p_vals, t_stats = (
254+
indices_matrix = (
255255
self._measures.pairwise_indices_for_subvar.values
256256
if self._cube.has_overlaps
257257
else self._measures.pairwise_indices.values
258258
)
259-
return self._assemble_pw_indices(
260-
p_vals, t_stats, self._alpha, self._only_larger
261-
)
259+
return self._assemble_matrix(self._remap_indices(indices_matrix))
262260

263261
@lazyproperty
264262
def pairwise_indices_alt(self):
265-
"""Optional 2D ndarray of tuple of int column-idxs.
263+
"""Optional 2D ndarray of tuple of int column-idxs pairwise-t alt threshold.
266264
267265
Represents the pairwise significance array of tuples considering the alternative
268266
threshold value.
269267
"""
270268
if self._alpha_alt is None:
271269
return None
272-
p_vals, t_stats = (
273-
self._measures.pairwise_indices_for_subvar.values
270+
indices_matrix = (
271+
self._measures.pairwise_indices_for_subvar_alt.values
274272
if self._cube.has_overlaps
275-
else self._measures.pairwise_indices.values
276-
)
277-
return self._assemble_pw_indices(
278-
p_vals, t_stats, self._alpha_alt, self._only_larger
273+
else self._measures.pairwise_indices_alt.values
279274
)
275+
return self._assemble_matrix(self._remap_indices(indices_matrix))
280276

281277
@lazyproperty
282278
def pairwise_means_indices(self):
@@ -287,14 +283,13 @@ def pairwise_means_indices(self):
287283
288284
Raises `ValueError` if the cube-result does not include `means` cube-measures.
289285
"""
290-
p_vals, t_stats = self._measures.pairwise_means_indices.values
291-
return self._assemble_pw_indices(
292-
p_vals, t_stats, self._alpha, self._only_larger
286+
return self._assemble_matrix(
287+
self._remap_indices(self._measures.pairwise_means_indices.values)
293288
)
294289

295290
@lazyproperty
296291
def pairwise_means_indices_alt(self):
297-
"""Optional 2D. ndarray of tuple of int column-idxs.
292+
"""Optional 2D ndarray of tuple of int column-idxs.
298293
299294
Represents the pairwise mean significance array of tuples considering the
300295
alternative threshold value.
@@ -303,9 +298,8 @@ def pairwise_means_indices_alt(self):
303298
"""
304299
if self._alpha_alt is None:
305300
return None
306-
p_vals, t_stats = self._measures.pairwise_means_indices.values
307-
return self._assemble_pw_indices(
308-
p_vals, t_stats, self._alpha_alt, self._only_larger
301+
return self._assemble_matrix(
302+
self._remap_indices(self._measures.pairwise_means_indices_alt.values)
309303
)
310304

311305
@lazyproperty
@@ -574,20 +568,22 @@ def rows_scale_median(self):
574568

575569
@lazyproperty
576570
def scale_mean_pairwise_indices(self):
577-
"""..."""
578-
p_vals, t_stats = self._measures.scale_mean_pairwise_indices.values
579-
return self._assemble_pw_scale_mean_indices(
580-
p_vals, t_stats, self._alpha, self._only_larger
571+
"""1D ndarray of tuple of int pairwise-t threshold for scale means."""
572+
return self._remap_indices(
573+
self._assemble_marginal(self._measures.scale_mean_pairwise_indices)
581574
)
582575

583576
@lazyproperty
584577
def scale_mean_pairwise_indices_alt(self):
585-
"""1D optional ndarray of tuple of int pairwise-t threshold for scale means."""
578+
"""Optional 1D ndarray of tuple of int pairwise-t threshold for scale means.
579+
580+
Represents the pairwise significance for scale means considering the
581+
alternative threshold value.
582+
"""
586583
if self._alpha_alt is None:
587584
return None
588-
p_vals, t_stats = self._measures.scale_mean_pairwise_indices.values
589-
return self._assemble_pw_scale_mean_indices(
590-
p_vals, t_stats, self._alpha_alt, self._only_larger
585+
return self._remap_indices(
586+
self._assemble_marginal(self._measures.scale_mean_pairwise_indices_alt)
591587
)
592588

593589
@lazyproperty
@@ -726,11 +722,6 @@ def zscores(self):
726722
"""
727723
return self._assemble_matrix(self._measures.zscores.blocks)
728724

729-
@lazyproperty
730-
def _alpha(self):
731-
"""float confidence-interval threshold for pairwise-t (sig) tests."""
732-
return self._columns_dimension.pairwise_significance_spec.alpha_values[0]
733-
734725
@lazyproperty
735726
def _alpha_alt(self):
736727
"""Alternate float confidence-interval threshold or None.
@@ -774,88 +765,6 @@ def _assemble_matrix(self, blocks):
774765
# --- desired output.
775766
return np.block(blocks)[np.ix_(self._row_order, self._column_order)]
776767

777-
def _assemble_pw_indices(self, p_vals, t_stats, alpha, only_larger):
778-
"""Return assembled 2D ndarray ot tuple of pairwise int indices.
779-
780-
Significance indices are calculated iterating over each ordered pvals and
781-
t_stats column and assembled into a 2D array.
782-
783-
This assembler method generates a 2D array of tuples of integers starting from
784-
t_stats and p_vals significance matrices:
785-
pvals:
786-
[[
787-
[0.1 0.2 0.3 ] pvals_col_0_selected
788-
[0.4 0.5 0.6 ]
789-
]
790-
[
791-
[0.01 0.02 0.3 ] pvals_col_1_selected
792-
[0.02 0.03 0.04]
793-
]]
794-
795-
t_stats:
796-
[[
797-
[0.1 0.2 0.3 ] t_stats_col_0_selected
798-
[0.4 0.5 0.6 ]
799-
]
800-
[
801-
[0.01 0.02 0.3 ] t_stats_col_1_selected
802-
[0.02 0.03 0.04]
803-
]]
804-
Each pvals and tstats matrix is used to calculate the 1D array of tuple of int
805-
that represents the significance for the selected column:
806-
e.g. [(0,),(), (1,2)]
807-
Iterating over each significance matrix the method assemble the complete matrix
808-
of significant indices:
809-
[[(0,), (), (1,2)],
810-
[(), (), (0,1]]
811-
"""
812-
813-
def pairwise_indices(p_vals, t_stats):
814-
"""1D ndarray containing tuples of int pairwise indices of each column."""
815-
significance = p_vals < alpha
816-
if only_larger:
817-
significance = np.logical_and(t_stats < 0, significance)
818-
col_significance = np.empty((len(significance),), dtype=object)
819-
col_significance[:] = [
820-
tuple(np.where(sig_row)[0]) for sig_row in significance
821-
]
822-
return col_significance
823-
824-
return np.array(
825-
[
826-
pairwise_indices(
827-
p_vals[i][np.ix_(self._row_order, self._column_order)],
828-
t_stats[i][np.ix_(self._row_order, self._column_order)],
829-
)
830-
for i in self._column_order
831-
]
832-
).T
833-
834-
def _assemble_pw_scale_mean_indices(self, p_vals, t_stats, alpha, only_larger):
835-
"""List of tuples indicating the significance of scale means values
836-
837-
Considering this output: [(3,), (2, 3), (3,), ()] and scale_means values
838-
[26, 30, 21, 11], each element contains a tuple of other element
839-
indices that are significantly different from the present element's
840-
index in a two-tailed test with alpha=.05 by default. The element at
841-
index 0 (26) indicates that it differs significantly only from the
842-
element at index 3 (11)
843-
"""
844-
845-
def scale_mean_pairwise_indices(pvals, tstats):
846-
"""Tuple of int pairwise indices of each column."""
847-
significance = pvals < alpha
848-
if only_larger:
849-
significance = np.logical_and(tstats < 0, significance)
850-
return tuple(np.where(significance)[0])
851-
852-
return [
853-
scale_mean_pairwise_indices(
854-
p_vals[i][self._column_order], t_stats[i][self._column_order]
855-
)
856-
for i in self._column_order
857-
]
858-
859768
def _assemble_vector(self, base_vector, subtotals, order, diffs_nan=False):
860769
"""Return 1D ndarray of `base_vector` with inserted `subtotals`, in `order`.
861770
@@ -928,10 +837,48 @@ def _measures(self):
928837
"""SecondOrderMeasures collection object for this cube-result."""
929838
return SecondOrderMeasures(self._cube, self._dimensions, self._slice_idx)
930839

931-
@lazyproperty
932-
def _only_larger(self):
933-
"""True if only the larger of reciprocal pairwise-t values should appear."""
934-
return self._columns_dimension.pairwise_significance_spec.only_larger
840+
def _remap_indices(self, indices_matrix):
841+
"""Remap pairwise indices from payload order to sort order.
842+
843+
Returns the significance indices of columns shifted according to the final
844+
column order and the eventual column insertions positions.
845+
846+
Considering a column_order == (0, 1, -1, 2, 3) with negative indices mapped to
847+
payload position of insertions
848+
849+
The column-order mapped to the payload positions will be (0, 1, 4, 2, 3) with
850+
(0, 1, 2, 3, 4*) as related sorted position (4* is a col insertion).
851+
852+
So, (1, 3, 4) should map to (1, 4, 2)
853+
"""
854+
n_col = len(self._columns_dimension.element_ids) + len(
855+
self._columns_dimension.insertion_ids
856+
)
857+
col_order = tuple((n_col + idx) % n_col for idx in self._column_order)
858+
# --- Mapping between payload-order indices and sorted positions (indices):
859+
# ---
860+
# --- {
861+
# --- 0: 0,
862+
# --- 1: 1,
863+
# --- 2: 3,
864+
# --- 3: 4,
865+
# --- 4: 2 # (-1)
866+
# --- }
867+
order_map = {k: v for v, k in enumerate(col_order)}
868+
remapped_indices = np.array(
869+
[
870+
tuple(
871+
sorted([order_map[idx] for idx in idxs if idx in order_map.keys()])
872+
)
873+
for idxs in indices_matrix.ravel()
874+
],
875+
dtype=object,
876+
)
877+
return (
878+
remapped_indices.reshape(indices_matrix.shape)
879+
if remapped_indices.size > 0
880+
else indices_matrix
881+
)
935882

936883
@lazyproperty
937884
def _row_order(self):

0 commit comments

Comments
 (0)