def set_data(self, data): # TODO: set xAxis resolution and tooltip time contents depending on # data.time_delta. See: http://imgur.com/yrnlgQz # If the same data is updated, short circuit to just updating the chart, # retaining all panels and list view selections ... if data is not None and self.data is not None and data.domain == self.data.domain: self.data = Timeseries.from_data_table(data) for config in self.configs: config.selection_changed() return self.data = data = None if data is None else Timeseries.from_data_table( data) if data is None: self.varmodel.clear() self.chart.clear() return if getattr(data.time_variable, 'utc_offset', False): offset_minutes = data.time_variable.utc_offset.total_seconds() / 60 self.chart.evalJS( 'Highcharts.setOptions({global: {timezoneOffset: %d}});' % -offset_minutes) # Why is this negative? It works. self.chart.chart() self.chart.setXAxisType('datetime' if (data.time_variable and ( getattr(data.time_variable, 'have_date', False) or getattr(data.time_variable, 'have_time', False))) else 'linear') self.varmodel.wrap([ var for var in data.domain.variables if var.is_continuous and var != data.time_variable ])
def set_data(self, data): # TODO: set xAxis resolution and tooltip time contents depending on # data.time_delta. See: http://imgur.com/yrnlgQz # If the same data is updated, short circuit to just updating the chart, # retaining all panels and list view selections ... if data is not None and self.data is not None and data.domain == self.data.domain: self.data = Timeseries.from_data_table(data) for config in self.configs: config.selection_changed() return self.data = data = None if data is None else Timeseries.from_data_table(data) if data is None: self.varmodel.clear() self.chart.clear() return if getattr(data.time_variable, 'utc_offset', False): offset_minutes = data.time_variable.utc_offset.total_seconds() / 60 self.chart.evalJS('Highcharts.setOptions({global: {timezoneOffset: %d}});' % -offset_minutes) # Why is this negative? It works. self.chart.chart() self.chart.setXAxisType( 'datetime' if (data.time_variable and (getattr(data.time_variable, 'have_date', False) or getattr(data.time_variable, 'have_time', False))) else 'linear') self.varmodel.wrap([var for var in data.domain.variables if var.is_continuous and var != data.time_variable])
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) def init_combos(): for combo in (self.combo_ax1, self.combo_ax2): combo.clear() self.attrlist_model[:] = [] for i in Spiralogram.AxesCategories: for combo in (self.combo_ax1, self.combo_ax2): combo.addItem(_enum_str(i)) for var in data.domain if data is not None else []: if (var.is_primitive() and (var is not data.time_variable or isinstance(var, TimeVariable) and data.time_delta is None)): self.attrlist_model.append(var) if var.is_discrete: for combo in (self.combo_ax1, self.combo_ax2): combo.addItem(gui.attributeIconDict[var], var.name) init_combos() self.chart.clear() if data is None: self.commit() return self.ax1 = 'months of year' self.ax2 = 'years' self.replot()
def set_data(self, data): slider = self.slider self.data = data = None if data is None else Timeseries.from_data_table(data) def disabled(): slider.setFormatter(str) slider.setHistogram(None) slider.setScale(0, 0) slider.setValues(0, 0) slider.setDisabled(True) self.send('Subset', None) if data is None: disabled() return if not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() disabled() return self.Error.clear() var = data.time_variable time_values = np.ravel(data[:, var]) # Save values for handler slider.time_values = time_values slider.setDisabled(False) slider.setHistogram(time_values) slider.setFormatter(var.repr_val) slider.setScale(time_values.min(), time_values.max()) self.valuesChanged(slider.minimumValue(), slider.maximumValue())
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) self.add_button.setDisabled(not len(getattr(data, 'domain', ()))) self.table_model.clear() if data is not None: self.var_model.wrap([var for var in data.domain if var.is_continuous and var is not data.time_variable]) self.on_changed()
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) self.add_button.setDisabled(not len(getattr(data, 'domain', ()))) self.table_model.clear() if data is not None: self.var_model.wrap([var for var in data.domain.variables if var.is_continuous and var is not data.time_variable]) self.on_changed()
def set_data(self, data): self.Error.clear() self.data = data = None if data is None else Timeseries.from_data_table(data) if data is None: self.commit() return if self.data.time_variable is None or not isinstance( self.data.time_variable, TimeVariable): self.Error.no_time_variable() self.commit() return def init_combos(): for model in (self.combo_ax1_model, self.combo_ax2_model): model.clear() newmodel = [] if data is not None and data.time_variable is not None: for model in (self.combo_ax1_model, self.combo_ax2_model): model[:] = [_enum_str(i) for i in Spiralogram.AxesCategories] for var in data.domain.variables if data is not None else []: if (var.is_primitive() and (var is not data.time_variable or isinstance(var, TimeVariable) and data.time_delta is None)): newmodel.append(var) if var.is_discrete: for model in (self.combo_ax1_model, self.combo_ax2_model): model.append(var) self.attrlist_model.wrap(newmodel) init_combos() self.chart.clear() self.closeContext() self.ax2 = next((self.combo_ax2.itemText(i) for i in range(self.combo_ax2.count())), '') self.ax1 = next((self.combo_ax1.itemText(i) for i in range(1, self.combo_ax1.count())), self.ax2) self.agg_attr = [data.domain.variables[0]] if len(data.domain.variables) else [] self.agg_func = 0 if getattr(data, 'time_variable', None) is not None: self.openContext(data.domain) if self.agg_attr: self.attrlist.blockSignals(True) self.attrlist.selectionModel().clear() for attr in self.agg_attr: try: row = self.attrlist_model.indexOf(attr) except ValueError: continue self.attrlist.selectionModel().select( self.attrlist_model.index(row), QItemSelectionModel.SelectCurrent) self.attrlist.blockSignals(False) self.replot()
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table( data) if data is not None: self.model.wrap([ var for var in data.domain if var.is_continuous and var is not data.time_variable ]) self.on_changed()
def test_time_var_removed(self): ts_with_tv = Timeseries.from_file('airpassengers') # select columns without time variable ts_without_tv = Timeseries.from_data_table( ts_with_tv[:, ts_with_tv.domain.class_var]) self.assertTrue(ts_with_tv.time_variable) # make sure the Timeseries without time variable in domain has # time_variable set to None self.assertIsNone(ts_without_tv.time_variable)
def test_too_many_periods(self): """ Do not crash when there are too many season periods. GH-38 """ w = self.widget time_series = Timeseries.from_data_table(Table("iris")[::30]) self.assertEqual(w.n_periods, 12) self.send_signal(w.Inputs.time_series, time_series) self.assertEqual(w.n_periods, 4)
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) self.all_attrs = [] if data is None: self.plot.clear() return self.all_attrs = [(var.name, gui.attributeIconDict[var]) for var in data.domain if (var is not data.time_variable and isinstance(var, ContinuousVariable))] self.attrs = [0] self.on_changed()
def set_data(self, data): self.Error.clear() self.data = data = None if data is None else \ Timeseries.from_data_table(data) if data is None: self.commit() return if self.data.time_variable is None or not isinstance( self.data.time_variable, TimeVariable): self.Error.no_time_variable() self.commit() return def init_combos(): for model in (self.combo_ax1_model, self.combo_ax2_model): model.clear() variables = [] if data is not None and data.time_variable is not None: for model in (self.combo_ax1_model, self.combo_ax2_model): model[:] = [ _enum_str(i) for i in Spiralogram.AxesCategories ] for var in data.domain.variables if data is not None else []: if (var.is_primitive() and (var is not data.time_variable or isinstance(var, TimeVariable) and data.time_delta.backwards_compatible_delta is None)): variables.append(var) if var.is_discrete: for model in (self.combo_ax1_model, self.combo_ax2_model): model.append(var) self.attrs_model[:] = variables init_combos() self.chart.clear() self.closeContext() self.ax2 = next((self.combo_ax2.itemText(i) for i in range(self.combo_ax2.count())), '') self.ax1 = next((self.combo_ax1.itemText(i) for i in range(1, self.combo_ax1.count())), self.ax2) self.agg_attr = data.domain[self.attrs_model[0]] if len( data.domain.variables) else None self.agg_func = DEFAULT_AGG_FUNC if getattr(data, 'time_variable', None) is not None: self.openContext(data.domain) self.update_agg_combo() self.replot()
def test_output(self): """ Adjusted values are added to the input data. """ w = self.widget w.autocommit = True time_series = Timeseries.from_data_table(Table("iris")) self.send_signal(w.Inputs.time_series, time_series) selmodel = w.view.selectionModel() selmodel.select(w.model.index(0), selmodel.Select) self.assertGreater(len(self.get_output("Time series").domain), len(time_series.domain))
def test_not_enough_instances(self): """ At least three instances are needed. GH-38 """ w = self.widget time_series = Timeseries.from_data_table(Table("iris")[:2]) self.assertFalse(w.Error.not_enough_instances.is_shown()) self.send_signal(w.Inputs.time_series, time_series) self.assertTrue(w.Error.not_enough_instances.is_shown()) self.send_signal(w.Inputs.time_series, None) self.assertFalse(w.Error.not_enough_instances.is_shown())
def commit(self): data = self.data if not data: self.Outputs.time_series.send(None) return # Group-by expects data sorted sorted_indices = np.argsort(data.time_values) if not np.all(sorted_indices == np.arange(len(data))): data = Timeseries.from_data_table( Table.from_table_rows(data, sorted_indices)) attrs, cvars, metas = [], [], [] for attr, _ in self.model: if attr in data.domain.attributes: attrs.append(attr) elif attr in data.domain.class_vars: cvars.append(attr) else: metas.append(attr) aggregate_time = self.AGG_TIME[self.agg_interval] def time_key(i): return timestamp( aggregate_time( fromtimestamp(data.time_values[i], tz=data.time_variable.timezone))) times = [] X, Y, M = [], [], [] for key_time, indices in groupby(np.arange(len(data)), key=time_key): times.append(key_time) subset = data[list(indices)] xs, ys, ms = [], [], [] for attr, func in self.model: values = Table.from_table( Domain([], [], [attr], source=data.domain), subset).metas out = (xs if attr in data.domain.attributes else ys if attr in data.domain.class_vars else ms) out.append(func(values)) X.append(xs) Y.append(ys) M.append(ms) ts = Timeseries.from_numpy( Domain([data.time_variable] + attrs, cvars, metas), np.column_stack((times, np.row_stack(X))), np.array(Y), np.array(np.row_stack(M), dtype=object)) self.Outputs.time_series.send(ts)
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) def init_combos(): for model in (self.combo_ax1_model, self.combo_ax2_model): model.clear() newmodel = [] if data is not None and data.time_variable is not None: for model in (self.combo_ax1_model, self.combo_ax2_model): model[:] = [_enum_str(i) for i in Spiralogram.AxesCategories] for var in data.domain.variables if data is not None else []: if (var.is_primitive() and (var is not data.time_variable or isinstance(var, TimeVariable) and data.time_delta is None)): newmodel.append(var) if var.is_discrete: for model in (self.combo_ax1_model, self.combo_ax2_model): model.append(var) self.attrlist_model.wrap(newmodel) init_combos() self.chart.clear() if data is None: self.commit() return self.closeContext() self.ax2 = next((self.combo_ax2.itemText(i) for i in range(self.combo_ax2.count())), '') self.ax1 = next((self.combo_ax1.itemText(i) for i in range(1, self.combo_ax1.count())), self.ax2) self.agg_attr = [data.domain.variables[0]] if len(data.domain.variables) else [] self.agg_func = 0 if getattr(data, 'time_variable', None) is not None: self.openContext(data.domain) if self.agg_attr: self.attrlist.blockSignals(True) self.attrlist.selectionModel().clear() for attr in self.agg_attr: try: row = self.attrlist_model.indexOf(attr) except ValueError: continue self.attrlist.selectionModel().select( self.attrlist_model.index(row), QItemSelectionModel.SelectCurrent) self.attrlist.blockSignals(False) self.replot()
def set_data(self, data): self.closeContext() self.data = data = None if data is None else \ Timeseries.from_data_table(data, detect_time_variable=True) if data is not None: self.model[:] = [var for var in data.domain.variables if var.is_continuous and var is not data.time_variable] self.select_default_variable() self.openContext(self.data) self._restore_selection() else: self.reset_model() self.on_changed()
def commit(self): data = self.data if not data: self.Outputs.time_series.send(None) return # Group-by expects data sorted sorted_indices = np.argsort(data.time_values) if not np.all(sorted_indices == np.arange(len(data))): data = Timeseries.from_data_table(Table.from_table_rows(data, sorted_indices)) attrs, cvars, metas = [], [], [] for attr, _ in self.model: if attr in data.domain.attributes: attrs.append(attr) elif attr in data.domain.class_vars: cvars.append(attr) else: metas.append(attr) aggreagate_time = self.AGG_TIME[self.agg_interval] def time_key(i): return timestamp(aggreagate_time(fromtimestamp(data.time_values[i]))) times = [] X, Y, M = [], [], [] for key_time, indices in groupby(np.arange(len(data)), key=time_key): times.append(key_time) subset = data[list(indices)] xs, ys, ms = [], [], [] for attr, func in self.model: values = Table.from_table(Domain([], [], [attr], source=data.domain), subset).metas out = (xs if attr in data.domain.attributes else ys if attr in data.domain.class_vars else ms) out.append(func(values)) X.append(xs) Y.append(ys) M.append(ms) ts = Timeseries( Domain([data.time_variable] + attrs, cvars, metas), np.column_stack((times, np.row_stack(X))), np.array(Y), np.array(np.row_stack(M), dtype=object)) self.Outputs.time_series.send(ts)
def test_bad_model(self): """ Do not fail on a bad model. GH-37 """ w = self.widget table = Table("housing") time_series = Timeseries.from_data_table(table) model = ARIMA((2, 5, 1), 0) self.assertFalse(w.Warning.model_not_appropriate.is_shown()) self.send_signal(w.Inputs.time_series, time_series) self.send_signal(w.Inputs.time_series_model, model, 0) w.controls.autocommit.click() self.assertTrue(w.Warning.model_not_appropriate.is_shown()) self.send_signal(w.Inputs.time_series_model, None, 0) self.assertFalse(w.Warning.model_not_appropriate.is_shown())
def set_data(self, data): self.store_transformations() self.closeContext() self.transformations = [] if data is None: self.data = None self.var_model.clear() else: self.data = Timeseries.from_data_table(data) self.var_model[:] = [ var for var in self.data.domain.variables if var.is_continuous and var is not self.data.time_variable] self.add_button.setDisabled(not self.var_model) self.openContext(self.var_model) self.table_model[:] = self.transformations self.on_changed()
def set_data(self, data): self.Error.not_enough_instances.clear() self.data = None self.model.clear() data = None if data is None else Timeseries.from_data_table(data) if data is None: pass elif len(data) > 2: self.data = data self.model.wrap([ var for var in data.domain.variables if var.is_continuous and var is not data.time_variable ]) self.controls.n_periods.setMaximum(min(MAX_PERIODS, len(data) - 1)) else: self.Error.not_enough_instances() self.on_changed()
def set_data(self, data): self.pack_settings() self.closeContext() self.Error.clear() data = None if data is None else Timeseries.from_data_table(data) if data is not None and not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() data = None self.data = data if data is None: self.model.clear() self.commit() return self.set_default(self.data) self.openContext(self.data) self.unpack_settings() self.commit()
def set_data(self, data): self.Error.no_instances.clear() self.data = data = None if data is None else \ Timeseries.from_data_table(data, detect_time_variable=True) self.all_attrs = [] if data is None: self.plot.clear() return if len(data) < 2: self.Error.no_instances() self.plot.clear() return self.all_attrs = [(var.name, gui.attributeIconDict[var]) for var in data.domain.variables if (var is not data.time_variable and isinstance(var, ContinuousVariable))] self.attrs = [0] self.on_changed()
def set_data(self, data): self.Error.clear() data = None if data is None else Timeseries.from_data_table(data) if data is not None and not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() data = None self.data = data if data is None: self.model.clear() self.commit() return self.model.wrap([[ attr, AGG_FUNCTIONS[0] if attr.is_continuous else Mode if attr.is_discrete else Concatenate if attr.is_string else None ] for attr in chain(data.domain, data.domain.metas) if attr != data.time_variable]) self.commit()
def set_data(self, data): self.Error.clear() data = None if data is None else Timeseries.from_data_table(data) if data is not None and not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() data = None self.data = data if data is None: self.model.clear() self.commit() return self.model.wrap([[attr, AGG_FUNCTIONS[0] if attr.is_continuous else Mode if attr.is_discrete else Concatenate if attr.is_string else None] for attr in chain(data.domain, data.domain.metas) if attr != data.time_variable]) self.commit()
def set_data(self, data): slider = self.slider self.data = data = None if data is None else Timeseries.from_data_table( data) def disabled(): slider.setFormatter(str) slider.setHistogram(None) slider.setScale(0, 0) slider.setValues(0, 0) slider.setDisabled(True) self.send('Subset', None) if data is None: disabled() return if not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() disabled() return self.Error.clear() var = data.time_variable time_values = data.time_values slider.setDisabled(False) slider.setHistogram(time_values) slider.setFormatter(var.repr_val) slider.setScale(time_values.min(), time_values.max()) self.valuesChanged(slider.minimumValue(), slider.maximumValue()) # Update datetime edit fields min_dt = QDateTime.fromMSecsSinceEpoch(time_values[0] * 1000).toUTC() max_dt = QDateTime.fromMSecsSinceEpoch(time_values[-1] * 1000).toUTC() self.date_from.setDateTimeRange(min_dt, max_dt) self.date_to.setDateTimeRange(min_dt, max_dt) date_format = ' '.join( (self.DATE_FORMATS[0] if var.have_date else '', self.DATE_FORMATS[1] if var.have_time else '')).strip() self.date_from.setDisplayFormat(date_format) self.date_to.setDisplayFormat(date_format)
def set_data(self, data): if data is None or not len(data): self.clear() return data = Timeseries.from_data_table(data) if not data.time_variable: self.clear() return time_values = np.sort(data.time_values) date_to = date_from = QDateTime.fromMSecsSinceEpoch(1000 * time_values[-1]).toUTC().date() if len(time_values) > 1: date_from = QDateTime.fromMSecsSinceEpoch(1000 * time_values[0]).toUTC().date() self.calendar.setDateRange(date_from, date_to) self.calendar.update() self.analog_clock.setTimeSpan(time_values) self.digital_clock.setTime(time_values[-1]) self.calendar.setDisabled(False) self.digital_clock.setDisabled(False)
def set_data(self, data): slider = self.slider self.data = data = None if data is None else Timeseries.from_data_table(data) def disabled(): slider.setFormatter(str) slider.setHistogram(None) slider.setScale(0, 0) slider.setValues(0, 0) self._set_disabled(True) self.Outputs.subset.send(None) if data is None: disabled() return if not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() disabled() return self.Error.clear() var = data.time_variable time_values = data.time_values self._set_disabled(False) slider.setHistogram(time_values) slider.setFormatter(var.repr_val) slider.setScale(time_values.min(), time_values.max()) self.valuesChanged(slider.minimumValue(), slider.maximumValue()) # Update datetime edit fields min_dt = QDateTime.fromMSecsSinceEpoch(time_values[0] * 1000).toUTC() max_dt = QDateTime.fromMSecsSinceEpoch(time_values[-1] * 1000).toUTC() self.date_from.setDateTimeRange(min_dt, max_dt) self.date_to.setDateTimeRange(min_dt, max_dt) date_format = ' '.join((self.DATE_FORMATS[0] if var.have_date else '', self.DATE_FORMATS[1] if var.have_time else '')).strip() self.date_from.setDisplayFormat(date_format) self.date_to.setDisplayFormat(date_format)
def set_data(self, data): if data is None or not len(data): self.clear() return data = Timeseries.from_data_table(data) if not data.time_variable: self.clear() return time_values = np.sort(data.time_values) date_to = date_from = QDateTime.fromMSecsSinceEpoch( 1000 * time_values[-1]).toUTC().date() if len(time_values) > 1: date_from = QDateTime.fromMSecsSinceEpoch( 1000 * time_values[0]).toUTC().date() self.calendar.setDateRange(date_from, date_to) self.calendar.update() self.analog_clock.setTimeSpan(time_values) self.digital_clock.setTime(time_values[-1]) self.calendar.setDisabled(False) self.digital_clock.setDisabled(False)
def finance_data(symbol, since=None, until=None, granularity='d'): """Fetch Yahoo Finance data for stock or index `symbol` within the period after `since` and before `until` (both inclusive). Parameters ---------- symbol: str A stock or index symbol, as supported by Yahoo Finance. since: date A start date (default: 1900-01-01). until: date An end date (default: today). granularity: 'd' or 'w' or 'm' or 'v' What data to get: daily, weekly, monthly, or dividends. Returns ------- data : Timeseries """ if since is None: since = date(1900, 1, 1) if until is None: until = date.today() f = web.DataReader(symbol, 'yahoo', since, until) data = Timeseries.from_data_table(table_from_frame(f)) # Make Adjusted Close a class variable attrs = [var.name for var in data.domain.attributes] attrs.remove('Adj Close') data = Timeseries.from_table( Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) data.name = symbol data.time_variable = data.domain['Date'] return data
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) self.update_model()
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table(data) if data is not None: self.model.wrap([var for var in data.domain if var.is_continuous and var is not data.time_variable]) self.on_changed()
def test_create_time_variable(self): table = Table("iris") time_series = Timeseries.from_data_table(table) id_1 = id(time_series.attributes) time_series.time_variable = time_series.domain.attributes[0] self.assertNotEqual(id_1, id(time_series.attributes))
def set_data(self, data): self.data = None if data is None else Timeseries.from_data_table(data) self.selected_attributes = None self._run() self.Outputs.selected_features.send(None)
def set_data(self, data): self.data = None if data is None else Timeseries.from_data_table(data) self.on_changed()
def interpolate_timeseries(data, method='linear', multivariate=False): """Return a new Timeseries (Table) with nan values interpolated. Parameters ---------- data : Orange.data.Table A table to interpolate. method : str {'linear', 'cubic', 'nearest', 'mean'} The interpolation method to use. multivariate : bool Whether to perform multivariate (2d) interpolation first. Univariate interpolation of same method is always performed as a final step. Returns ------- series : Timeseries A table with nans in original replaced with interpolated values. """ from scipy.interpolate import griddata, interp1d from Orange.data import Domain from orangecontrib.timeseries import Timeseries attrs = data.domain.attributes cvars = data.domain.class_vars metas = data.domain.metas X = data.X.copy() Y = np.column_stack((data.Y, )).copy() # make 2d M = data.metas.copy() # Interpolate discrete columns to mode/nearest value _x = Timeseries.from_data_table(data).time_values.astype(float) for A, vars in ((X, attrs), (Y, cvars)): for i, var in enumerate(vars): if not var.is_discrete: continue vals = A[:, i] isnan = np.isnan(vals) if not isnan.any(): continue if method == 'nearest': nonnan = ~isnan x, vals = _x[nonnan], vals[nonnan] f = interp1d(x, vals, kind='nearest', copy=False, assume_sorted=True) A[isnan, i] = f(_x)[isnan] continue A[isnan, i] = np.argmax(np.bincount(vals[~isnan].astype(int))) # Interpolate data if multivariate and method != 'mean': for A, vars in ((X, attrs), (Y, cvars)): is_continuous = [var.is_continuous for var in vars] if sum(is_continuous) < 3 or A.shape[0] < 3: # griddata() doesn't work with 1d data continue # Only multivariate continuous features Acont = A[:, is_continuous] isnan = np.isnan(Acont) if not isnan.any(): continue nonnan = ~isnan vals = griddata(nonnan.nonzero(), Acont[nonnan], isnan.nonzero(), method=method) Acont[isnan] = vals A[:, is_continuous] = Acont # Do the 1d interpolation anyway in case 2d left some nans for A in (X, Y): for i, col in enumerate(A.T): isnan = np.isnan(col) # there is no need to interpolate if there are no nans # there needs to be at least two numbers if not isnan.any() or sum(~isnan) < 2: continue # Mean interpolation if method == 'mean': A[isnan, i] = np.nanmean(col) continue nonnan = ~isnan f = interp1d(_x[nonnan], col[nonnan], kind=method, copy=False, assume_sorted=True, bounds_error=False) A[isnan, i] = f(_x[isnan]) # nearest-interpolate any nans at vals start and end # TODO: replace nearest with linear/OLS? valid = (~np.isnan(col)).nonzero()[0] first, last = valid[0], valid[-1] col[:first] = col[first] col[last:] = col[last] ts = Timeseries.from_numpy(Domain(attrs, cvars, metas), X, Y, M) return ts
def set_data(self, data): self.data = data = None if data is None else Timeseries.from_data_table( data) self.update_model()
def set_data(self, data): slider = self.slider self.data = data = None if data is None else Timeseries.from_data_table( data) def disabled(): slider.setFormatter(str) slider.setHistogram(None) slider.setScale(0, 0, None) slider.setValues(0, 0) self._set_disabled(True) self.Outputs.subset.send(None) if data is None: disabled() return if not isinstance(data.time_variable, TimeVariable): self.Error.no_time_variable() disabled() return if not data.time_delta.deltas: self.Error.no_time_delta() disabled() return self.Error.clear() var = data.time_variable time_values = data.time_values min_dt = datetime.datetime.fromtimestamp(round(time_values.min()), tz=datetime.timezone.utc) max_dt = datetime.datetime.fromtimestamp(round(time_values.max()), tz=datetime.timezone.utc) # Depending on time delta: # - set slider maximum (granularity) # - set range for end dt (+ 1 timedelta) # - set date format # - set time overlap options delta = data.time_delta.gcd range = max_dt - min_dt if isinstance(delta, Number): maximum = round(range.total_seconds() / delta) timedelta = datetime.timedelta(milliseconds=delta * 1000) min_dt2 = min_dt + timedelta max_dt2 = max_dt + timedelta if delta >= 86400: # more than a day date_format = ''.join(self.DATE_FORMATS[0:3]) else: date_format = ''.join(self.DATE_FORMATS) for k, n in [(k, n) for k, n in self.STEP_SIZES.items() if isinstance(n, Number)]: if delta <= n: min_overlap = k break else: min_overlap = '1 day' else: # isinstance(delta, tuple) if delta[1] == 'month': months = (max_dt.year - min_dt.year) * 12 + \ (max_dt.month - min_dt.month) maximum = months / delta[0] if min_dt.month < 12 - delta[0]: min_dt2 = min_dt.replace(month=min_dt.month + delta[0]) else: min_dt2 = min_dt.replace(year=min_dt.year + 1, month=12 - min_dt.month + delta[0]) if max_dt.month < 12 - delta[0]: max_dt2 = max_dt.replace(month=max_dt.month + delta[0]) else: max_dt2 = max_dt.replace(year=max_dt.year + 1, month=12 - min_dt.month + delta[0]) date_format = ''.join(self.DATE_FORMATS[0:2]) for k, (i, u) in [(k, v) for k, v in self.STEP_SIZES.items() if isinstance(v, tuple) and v[1] == 'month']: if delta[0] <= i: min_overlap = k break else: min_overlap = '1 year' else: # elif delta[1] == 'year': years = max_dt.year - min_dt.year maximum = years / delta[0] min_dt2 = min_dt.replace(year=min_dt.year + delta[0], ) max_dt2 = max_dt.replace(year=max_dt.year + delta[0], ) date_format = self.DATE_FORMATS[0] for k, (i, u) in [(k, v) for k, v in self.STEP_SIZES.items() if isinstance(v, tuple) and v[1] == 'year']: if delta[0] <= i: min_overlap = k break else: raise Exception('Timedelta larger than 100 years') # find max sensible time overlap upper_overlap_limit = range / 2 for k, overlap in self.STEP_SIZES.items(): if isinstance(overlap, Number): if upper_overlap_limit.total_seconds() <= overlap: max_overlap = k break else: i, u = overlap if u == 'month': month_diff = (max_dt.year - min_dt.year) * 12 \ + max(0, max_dt.month - min_dt.month) if month_diff / 2 <= i: max_overlap = k break else: # if u == 'year': year_diff = max_dt.year - min_dt.year if year_diff / 2 <= i: max_overlap = k break else: # last item in step sizes *_, max_overlap = self.STEP_SIZES.keys() self.stepsize_combobox.clear() dict_iter = iter(self.STEP_SIZES.keys()) next_item = next(dict_iter) while next_item != min_overlap: next_item = next(dict_iter) self.stepsize_combobox.addItem(next_item) self.step_size = next_item while next_item != max_overlap: next_item = next(dict_iter) self.stepsize_combobox.addItem(next_item) slider.setMinimum(0) slider.setMaximum(maximum + 1) self._set_disabled(False) slider.setHistogram(time_values) slider.setFormatter(var.repr_val) slider.setScale(time_values.min(), time_values.max(), data.time_delta.gcd) self.sliderValuesChanged(slider.minimumValue(), slider.maximumValue()) def utc_dt(dt): qdt = QDateTime(dt) qdt.setTimeZone(QTimeZone.utc()) return qdt self.date_from.setDateTimeRange(utc_dt(min_dt), utc_dt(max_dt)) self.date_to.setDateTimeRange(utc_dt(min_dt2), utc_dt(max_dt2)) self.date_from.setDisplayFormat(date_format) self.date_to.setDisplayFormat(date_format) def format_time(i): dt = QDateTime.fromMSecsSinceEpoch(i * 1000).toUTC() return dt.toString(date_format) self.slider.setFormatter(format_time)
def set_data(self, data): self.data = data = None if data is None else \ Timeseries.from_data_table(data, detect_time_variable=True) self.on_changed()