@@ -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