@@ -68,6 +68,7 @@ class Pivot:
6868 ContVarFunctions = (Sum , Mean , Min , Max , Mode , Median , Var )
6969 DiscVarFunctions = (Majority ,)
7070 TimeVarFunctions = (Mean , Min , Max , Mode , Median )
71+ FloatFunctions = (Count , Count_defined , Sum , Var )
7172
7273 class Tables :
7374 table = None # type: Table
@@ -303,11 +304,23 @@ def map_values(index, _X):
303304 _X [:, index ][_X [:, index ] == value ] = j
304305 return values
305306
307+ create_time_var = \
308+ isinstance (val_var , TimeVariable ) and \
309+ all (fun in self .TimeVarFunctions for fun in agg_funs )
310+ create_cont_var = \
311+ not val_var or val_var .is_continuous and \
312+ (not isinstance (val_var , TimeVariable ) or
313+ all (fun in self .FloatFunctions for fun in agg_funs ))
314+
306315 vals = np .array (self ._col_var .values )[self ._col_var_groups .astype (int )]
307- if not val_var or val_var .is_continuous :
308- cv = ContinuousVariable
309- attrs = [[cv (f"{ v } " , 1 ) for v in vals ]] * 2
310- attrs .extend ([[cv ("Total" , 1 )]] * 2 )
316+ if create_time_var :
317+ kwargs = {"have_date" : val_var .have_date ,
318+ "have_time" : val_var .have_time }
319+ attrs = [[TimeVariable (f"{ v } " , ** kwargs ) for v in vals ]] * 2
320+ attrs .extend ([[TimeVariable ("Total" , ** kwargs )]] * 2 )
321+ elif create_cont_var :
322+ attrs = [[ContinuousVariable (f"{ v } " , 1 ) for v in vals ]] * 2
323+ attrs .extend ([[ContinuousVariable ("Total" , 1 )]] * 2 )
311324 else :
312325 attrs = []
313326 for x in (X , X_h ):
@@ -354,15 +367,19 @@ def __get_pivot_tab_x(self, val_var, agg_funs):
354367 gt = self ._group_tables
355368 n_fun = len (agg_funs )
356369 n_rows , n_cols = len (self ._row_var_groups ), len (self ._col_var_groups )
357- kwargs = {"fill_value" : np .nan , "dtype" : float } \
358- if not val_var or val_var .is_continuous \
370+ is_float_type = not val_var or val_var .is_continuous
371+ if isinstance (val_var , TimeVariable ):
372+ is_float_type = \
373+ all (fun in self .TimeVarFunctions for fun in agg_funs ) or \
374+ all (fun in self .FloatFunctions for fun in agg_funs )
375+ kwargs = {"fill_value" : np .nan , "dtype" : float } if is_float_type \
359376 else {"fill_value" : "" , "dtype" : object }
360377 X = np .full ((n_rows * n_fun , 2 + n_cols ), ** kwargs )
361378 X_h = np .full ((n_fun , 2 + n_cols ), ** kwargs )
362379 X_v = np .full ((n_rows * n_fun , 1 ), ** kwargs )
363380 X_t = np .full ((n_fun , 1 ), ** kwargs )
364381 for i , fun in enumerate (agg_funs ):
365- args = (val_var , fun )
382+ args = (val_var , fun , is_float_type )
366383 X [i ::n_fun , 2 :] = self .__rows_for_function (n_rows , n_cols , * args )
367384 X [i ::n_fun , :2 ] = np .array ([[row_val , agg_funs .index (fun )] for
368385 row_val in self ._row_var_groups ])
@@ -372,13 +389,14 @@ def __get_pivot_tab_x(self, val_var, agg_funs):
372389 X_t [i ] = self .__total_for_function (gt .total , * args )
373390 return X , X_h , X_v , X_t
374391
375- def __total_for_function (self , group_tab , val_var , fun ):
392+ def __total_for_function (self , group_tab , val_var , fun , is_float_type ):
376393 ref = self ._indepen_agg_done .get (fun , None ) \
377394 or self ._depen_agg_done [fun ][val_var ]
378395 ref -= int (bool (not self .single_var_grouping ))
379- return self .__check_continuous (val_var , group_tab .X [:, ref ], fun )
396+ return self .__check_continuous (val_var , group_tab .X [:, ref ],
397+ fun , is_float_type )
380398
381- def __rows_for_function (self , n_rows , n_cols , val_var , fun ):
399+ def __rows_for_function (self , n_rows , n_cols , val_var , fun , is_float_type ):
382400 ref = self ._indepen_agg_done .get (fun , None ) \
383401 or self ._depen_agg_done [fun ][val_var ]
384402 column = self ._group_tables .table .X [:, ref ]
@@ -387,14 +405,23 @@ def __rows_for_function(self, n_rows, n_cols, val_var, fun):
387405 rows [np .diag_indices_from (rows )] = column
388406 else :
389407 rows = column .reshape (n_rows , n_cols )
390- return self .__check_continuous (val_var , rows , fun )
408+ return self .__check_continuous (val_var , rows , fun , is_float_type )
391409
392- def __check_continuous (self , val_var , column , fun ):
410+ def __check_continuous (self , val_var , column , fun , is_float_type ):
393411 if val_var and not val_var .is_continuous :
394412 column = column .astype (str )
395413 if fun in self .DiscVarFunctions :
396414 for j , val in enumerate (val_var .values ):
397415 column [column == str (float (j ))] = val
416+ elif isinstance (val_var , TimeVariable ) and not is_float_type :
417+ shape = column .shape
418+ column = column .flatten ()
419+ column_ = column .astype (str )
420+ if fun in self .TimeVarFunctions :
421+ for i in range (column .shape [0 ]):
422+ if not np .isnan (column [i ]):
423+ column_ [i ] = val_var .repr_val (column [i ])
424+ return column_ .reshape (shape )
398425 return column
399426
400427 @staticmethod
@@ -618,10 +645,8 @@ def __set_vertical_headers(self, table):
618645 self .table_model .setItem (i + 1 , 1 , item )
619646
620647 def _set_values (self , table ):
621- attrs = table .domain .attributes
622648 for i , j in product (range (len (table )), range (len (table [0 ]))):
623- # data is read faster when reading directly from table.X
624- value = table .X [i , j ] if attrs [j ].is_continuous else table [i , j ]
649+ value = table [i , j ]
625650 item = self ._create_value_item (str (value ))
626651 self .table_model .setItem (i + self ._n_leading_rows ,
627652 j + self ._n_leading_cols , item )
@@ -982,9 +1007,10 @@ def get_filtered_data(self):
9821007 elif isinstance (at , ContinuousVariable ):
9831008 f .append (FilterContinuous (at , FilterContinuous .Equal , val ))
9841009 cond .append (Values (f ))
985- return Values ([ f for f in cond ] , conjunction = False )(self .data )
1010+ return Values (cond , conjunction = False )(self .data )
9861011
987- def sizeHint (self ):
1012+ @staticmethod
1013+ def sizeHint ():
9881014 return QSize (640 , 525 )
9891015
9901016 def send_report (self ):
0 commit comments