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 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() YAHOO_URL = ('http://chart.finance.yahoo.com/table.csv?' 's={SYMBOL}&d={TO_MONTH}&e={TO_DAY}&f={TO_YEAR}&' 'g={GRANULARITY}&a={FROM_MONTH}&b={FROM_DAY}&c={FROM_YEAR}&ignore=.csv') url = YAHOO_URL.format(SYMBOL=symbol, GRANULARITY=granularity, TO_MONTH=until.month - 1, TO_DAY=until.day, TO_YEAR=until.year, FROM_MONTH=since.month - 1, FROM_DAY=since.day, FROM_YEAR=since.year) data = Timeseries.from_url(url)[::-1] # Make Adjusted Close a class variable attrs = [var.name for var in data.domain.attributes] attrs.remove('Adj Close') data = Timeseries(Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) data.name = symbol data.time_variable = data.domain['Date'] return data
def test_nan_timeseries(self): """ Widget used to crash because interpolation crashed when there was a column with all nans or all nuns and only one number. Now interpolation is skipped. GH-27 """ time_series = Timeseries( Domain(attributes=[ContinuousVariable("a"), ContinuousVariable("b")]), list(zip(list(range(5)), list(range(5)))) ) time_series.X[:, 1] = np.nan self.send_signal(self.widget.Inputs.time_series, time_series) time_series.X[2, 1] = 42 self.send_signal(self.widget.Inputs.time_series, time_series)
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 quandl_data(symbol, since=None, until=None, *, collapse='daily', api_key=''): """ Parameters ---------- symbol since until collapse: none|daily|weekly|monthly|quarterly|annual api_key Returns ------- """ if since is None: since = date(1900, 1, 1).isoformat() if until is None: until = date.today().isoformat() QUANDL_URL = ('https://www.quandl.com/api/v3/datasets/WIKI/{SYMBOL}/data.csv?' 'start_date={START_DATE}&end_date={END_DATE}&order=asc&' 'collapse={COLLAPSE}&transform=rdiff&api_key={API_KEY}') url = QUANDL_URL.format(SYMBOL=symbol, START_DATE=since, END_DATE=until, COLLAPSE=collapse, API_KEY=api_key) ts = Timeseries.from_url(url) return ts
def _as_table(self, values, what): """Used for residuals() and fittedvalues() methods.""" from Orange.data import Domain, ContinuousVariable attrs = [] n_vars = values.shape[1] if values.ndim == 2 else 1 if n_vars == 1: values = np.atleast_2d(values).T tvar = None # If 1d, time var likely not already present, so lets add it if possible if n_vars == 1 and self._table_timevar: values = np.column_stack((self._table_timevals[-values.shape[0]:], values)) tvar = self._table_timevar attrs.append(tvar) for i, name in zip(range(n_vars), self._table_var_names or range(n_vars)): attrs.append(ContinuousVariable('{} ({})'.format(name, what))) # Make the fitted time variable time variable if self._table_timevar and self._table_timevar.name == name: tvar = attrs[-1] table = Timeseries.from_numpy(Domain(attrs), values) table.time_variable = tvar table.name = (self._table_name or '') + '({} {})'.format(self, what) return table
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): 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 commit(self): data = self.data if not data or not self.selected: self.send(Output.TIMESERIES, data) return selected_subset = Timeseries(Domain(self.selected, source=data.domain), data) # FIXME: might not pass selected interpolation method with self.progressBar(len(self.selected)) as progress: adjusted_data = seasonal_decompose( selected_subset, self.DECOMPOSITION_MODELS[self.decomposition], self.n_periods, callback=lambda *_: progress.advance()) ts = Timeseries(Timeseries.concatenate((data, adjusted_data))) ts.time_variable = data.time_variable self.send(Output.TIMESERIES, ts)
def commit(self): data = self.data if not data or not len(self.selected): self.send(Output.TIMESERIES, None) return X = [] attrs = [] invert = self.invert_direction shift = self.shift_period order = self.diff_order for var in self.selected: col = np.ravel(data[:, var]) if invert: col = col[::-1] out = np.empty(len(col)) if shift == 1: out[:-order] = np.diff(col, order) out[-order:] = np.nan else: out[:-shift] = col[shift:] - col[:-shift] out[-shift:] = np.nan if invert: out = out[::-1] X.append(out) template = '{} (diff; {})'.format(var, 'order={}'.format(order) if shift == 1 else 'shift={}'.format(shift)) name = available_name(data.domain, template) attrs.append(ContinuousVariable(name)) ts = Timeseries(Domain(data.domain.attributes + tuple(attrs), data.domain.class_vars, data.domain.metas), np.column_stack((data.X, np.column_stack(X))), data.Y, data.metas) ts.time_variable = data.time_variable self.send(Output.TIMESERIES, ts)
def test_output_metas(self): """ Do not create 3-dimensional numpy metas array. GH-44 """ w = self.widget data = Timeseries("airpassengers") new_domain = Domain( attributes=data.domain.attributes, class_vars=data.domain.class_vars, metas=[DiscreteVariable("meta", values=["0"])] ) data = data.transform(new_domain) data.metas = np.zeros((144, 1), dtype=object) self.assertEqual(len(data.metas.shape), 2) self.send_signal(w.Inputs.time_series, data) w.controls.autocommit.click() output = self.get_output(w.Outputs.time_series) self.assertEqual(len(output.metas.shape), 2)
def commit(self): data = self.data self.Error.clear() if data is None or (self.selected_attr not in data.domain and not self.radio_sequential): self.Outputs.time_series.send(None) return attrs = data.domain.attributes cvars = data.domain.class_vars metas = data.domain.metas X = data.X Y = np.column_stack((data.Y,)) # make 2d M = data.metas # Set sequence attribute if self.radio_sequential: for i in chain(('',), range(10)): name = '__seq__' + str(i) if name not in data.domain: break time_var = ContinuousVariable(name) attrs = attrs.__class__((time_var,)) + attrs X = np.column_stack((np.arange(1, len(data) + 1), X)) data = Table(Domain(attrs, cvars, metas), X, Y, M) else: # Or make a sequence attribute one of the existing attributes # and sort all values according to it time_var = data.domain[self.selected_attr] values = Table.from_table(Domain([], [], [time_var]), source=data).metas.ravel() if np.isnan(values).any(): self.Error.nan_times(time_var.name) self.Outputs.time_series.send(None) return ordered = np.argsort(values) if (ordered != np.arange(len(ordered))).any(): data = data[ordered] ts = Timeseries(data.domain, data) # TODO: ensure equidistant ts.time_variable = time_var 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) 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.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 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(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(Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) data.name = symbol data.time_variable = data.domain['Date'] return data
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 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 _predict_as_table(self, prediction, confidence): from Orange.data import Domain, ContinuousVariable means, lows, highs = [], [], [] n_vars = prediction.shape[2] if len(prediction.shape) > 2 else 1 for i, name in zip(range(n_vars), self._table_var_names or range(n_vars)): mean = ContinuousVariable('{} (forecast)'.format(name)) low = ContinuousVariable('{} ({:d}%CI low)'.format(name, confidence)) high = ContinuousVariable('{} ({:d}%CI high)'.format(name, confidence)) low.ci_percent = high.ci_percent = confidence mean.ci_attrs = (low, high) means.append(mean) lows.append(low) highs.append(high) domain = Domain(means + lows + highs) X = np.column_stack(prediction) table = Timeseries.from_numpy(domain, X) table.name = (self._table_name or '') + '({} forecast)'.format(self) return table
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 quandl_data(symbol, since=None, until=None, *, collapse='daily', api_key=''): """ Parameters ---------- symbol since until collapse: none|daily|weekly|monthly|quarterly|annual api_key Returns ------- """ if since is None: since = date(1900, 1, 1).isoformat() if until is None: until = date.today().isoformat() QUANDL_URL = ( 'https://www.quandl.com/api/v3/datasets/WIKI/{SYMBOL}/data.csv?' 'start_date={START_DATE}&end_date={END_DATE}&order=asc&' 'collapse={COLLAPSE}&transform=rdiff&api_key={API_KEY}') url = QUANDL_URL.format(SYMBOL=symbol, START_DATE=since, END_DATE=until, COLLAPSE=collapse, API_KEY=api_key) ts = Timeseries.from_url(url) return ts
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(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( Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) data.name = symbol data.time_variable = data.domain['Date'] return data
self.on_changed() def on_changed(self): if not self.attrs or not self.all_attrs: return options = dict(series=[]) for attr in self.attrs: attr_name = self.all_attrs[attr][0] periods, pgram = self.periodogram(attr_name) options['series'].append( dict(data=np.column_stack((periods, pgram)), name=attr_name)) self.plot.chart(options) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWPeriodogram() data = Timeseries('yahoo_MSFT') data = Timeseries('autoroute') # data = Timeseries('UCI-SML2010-1') ow.set_data(data) ow.show() a.exec_()
def moving_transform(data, spec, fixed_wlen=0): """ Return data transformed according to spec. Parameters ---------- data : Timeseries A table with features to transform. spec : list of lists A list of lists [feature:Variable, window_length:int, function:callable]. fixed_wlen : int If not 0, then window_length in spec is disregarded and this length is used. Also the windows don't shift by one but instead align themselves side by side. Returns ------- transformed : Timeseries A table of original data its transformations. """ from itertools import chain from Orange.data import ContinuousVariable, Domain from orangecontrib.timeseries import Timeseries from orangecontrib.timeseries.widgets.utils import available_name from orangecontrib.timeseries.agg_funcs import Cumulative_sum, Cumulative_product X = [] attrs = [] for var, wlen, func in spec: col = np.ravel(data[:, var]) if fixed_wlen: wlen = fixed_wlen if func in (Cumulative_sum, Cumulative_product): out = list(chain.from_iterable(func(col[i:i + wlen]) for i in range(0, len(col), wlen))) else: # In reverse cause lazy brain. Also prefer informative ends, not beginnings as much col = col[::-1] out = [func(col[i:i + wlen]) for i in range(0, len(col), wlen if bool(fixed_wlen) else 1)] out = out[::-1] X.append(out) template = '{} ({}; {})'.format(var.name, wlen, func.__name__.lower().replace('_', ' ')) name = available_name(data.domain, template) attrs.append(ContinuousVariable(name)) dataX, dataY, dataM = data.X, data.Y, data.metas if fixed_wlen: n = len(X[0]) dataX = dataX[::-1][::fixed_wlen][:n][::-1] dataY = dataY[::-1][::fixed_wlen][:n][::-1] dataM = dataM[::-1][::fixed_wlen][:n][::-1] ts = Timeseries(Domain(data.domain.attributes + tuple(attrs), data.domain.class_vars, data.domain.metas), np.column_stack( (dataX, np.column_stack(X))) if X else dataX, dataY, dataM) ts.time_variable = data.time_variable return ts
gui.checkBox(box, self, 'use_exog', 'Use exogenous (independent) variables (ARMAX)', callback=self.apply) def forecast(self, model): if self.use_exog and self.exog_data is None: return return model.predict(self.forecast_steps, exog=self.exog_data, alpha=1 - self.forecast_confint / 100, as_table=True) def create_learner(self): return ARIMA((self.p, self.d, self.q), self.use_exog) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication from Orange.data import Domain a = QApplication([]) ow = OWARIMAModel() data = Timeseries('airpassengers') domain = Domain(data.domain.attributes[:-1], data.domain.attributes[-1]) data = Timeseries.from_numpy(domain, data.X[:, :-1], data.X[:, -1]) ow.set_data(data) ow.show() a.exec()
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.on_changed()
def moving_transform(data, spec, fixed_wlen=0): """ Return data transformed according to spec. Parameters ---------- data : Timeseries A table with features to transform. spec : list of lists A list of lists [feature:Variable, window_length:int, function:callable]. fixed_wlen : int If not 0, then window_length in spec is disregarded and this length is used. Also the windows don't shift by one but instead align themselves side by side. Returns ------- transformed : Timeseries A table of original data its transformations. """ from itertools import chain from Orange.data import ContinuousVariable, Domain from orangecontrib.timeseries import Timeseries from orangecontrib.timeseries.widgets.utils import available_name from orangecontrib.timeseries.agg_funcs import Cumulative_sum, Cumulative_product X = [] attrs = [] for var, wlen, func in spec: col = np.ravel(data[:, var]) if fixed_wlen: wlen = fixed_wlen if func in (Cumulative_sum, Cumulative_product): out = list( chain.from_iterable( func(col[i:i + wlen]) for i in range(0, len(col), wlen))) else: # In reverse cause lazy brain. Also prefer informative ends, not beginnings as much col = col[::-1] out = [ func(col[i:i + wlen]) for i in range(0, len(col), wlen if bool(fixed_wlen) else 1) ] out = out[::-1] X.append(out) template = '{} ({}; {})'.format( var.name, wlen, func.__name__.lower().replace('_', ' ')) name = available_name(data.domain, template) attrs.append(ContinuousVariable(name)) dataX, dataY, dataM = data.X, data.Y, data.metas if fixed_wlen: n = len(X[0]) dataX = dataX[::-1][::fixed_wlen][:n][::-1] dataY = dataY[::-1][::fixed_wlen][:n][::-1] dataM = dataM[::-1][::fixed_wlen][:n][::-1] ts = Timeseries.from_numpy( Domain(data.domain.attributes + tuple(attrs), data.domain.class_vars, data.domain.metas), np.column_stack((dataX, np.column_stack(X))) if X else dataX, dataY, dataM) ts.time_variable = data.time_variable return ts
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()
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) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWAggregate() ow.set_data(Timeseries('airpassengers')) ow.show() a.exec()
def setSeries(self, timeseries, attr, xdim, ydim, fagg): if timeseries is None or not attr: self.clear() return # TODO: support discrete variables if isinstance(xdim, str) and xdim.isdigit(): xdim = [str(i) for i in range(1, int(xdim) + 1)] if isinstance(ydim, str) and ydim.isdigit(): ydim = [str(i) for i in range(1, int(ydim) + 1)] xvals, xfunc = xdim.value yvals, yfunc = ydim.value values = Timeseries(Domain([], [], attr, source=timeseries.domain), timeseries).metas time_values = np.ravel(timeseries[:, timeseries.time_variable]) if True: fromtimestamp = datetime.fromtimestamp time_values = [fromtimestamp(i) for i in time_values] if not yvals: yvals = sorted(set(yfunc(i) for i in time_values)) if not xvals: xvals = sorted(set(xfunc(i) for i in time_values)) indices = defaultdict(list) for i, tval in enumerate(time_values): indices[(xfunc(tval), yfunc(tval))].append(i) series = [] aggvals = [] self.indices = [] xname = self.AxesCategories.name_it(xdim) yname = self.AxesCategories.name_it(ydim) for yval in yvals: data = [] series.append(dict(name=yname(yval), data=data)) self.indices.append([]) for xval in xvals: inds = indices.get((xval, yval), ()) self.indices[-1].append(inds) point = dict(y=1) data.append(point) if inds: try: aggval = fagg(values[inds]) except ValueError: aggval = np.nan else: aggval = np.nan if np.isnan(aggval): aggval = 'NaN' point['select'] = '' point['color'] = 'white' else: aggvals.append(aggval) point['n'] = aggval # TODO: allow scaling over just rows or cols instead of all values as currently try: maxval, minval = np.max(aggvals), np.min(aggvals) except ValueError: self.clear() return ptpval = maxval - minval color = GradientPaletteGenerator('#ffcccc', '#cc0000') selected_color = GradientPaletteGenerator('#ccffcc', '#006600') for serie in series: for point in serie['data']: n = point['n'] if isinstance(n, Number): val = (n - minval) / ptpval point['color'] = color[val] point['states'] = dict(select=dict(color=selected_color[val])) # TODO: make a white hole in the middle. Center w/o data. self.chart(series=series, xAxis_categories=[xname(i) for i in xvals], yAxis_categories=[yname(i) for i in reversed(yvals)])
self.varmodel.wrap([var for var in data.domain.variables if var.is_continuous and var != data.time_variable]) @Inputs.forecast def set_forecast(self, forecast, id): if forecast is not None: self.forecasts[id] = forecast else: self.forecasts.pop(id, None) # TODO: update currently shown plots if __name__ == "__main__": from AnyQt.QtWidgets import QApplication from orangecontrib.timeseries import ARIMA, VAR a = QApplication([]) ow = OWLineChart() airpassengers = Timeseries('airpassengers') ow.set_data(airpassengers), msft = airpassengers.interp() model = ARIMA((3, 1, 1)).fit(airpassengers) ow.set_forecast(model.predict(10, as_table=True), 0) model = VAR(4).fit(msft) ow.set_forecast(model.predict(10, as_table=True), 1) ow.show() a.exec()
self.chart.enable_rangeSelector( isinstance(data.time_variable, TimeVariable)) def set_forecast(self, forecast, id): if forecast is not None: self.forecasts[id] = forecast else: self.forecasts.pop(id, None) # TODO: update currently shown plots if __name__ == "__main__": from PyQt4.QtGui import QApplication from orangecontrib.timeseries import ARIMA, VAR a = QApplication([]) ow = OWLineChart() msft = Timeseries('yahoo_MSFT') ow.set_data(msft), # ow.set_data(Timeseries('UCI-SML2010-1')) msft = msft.interp() model = ARIMA((3, 1, 1)).fit(msft) ow.set_forecast(model.predict(10, as_table=True), 0) model = VAR(4).fit(msft) ow.set_forecast(model.predict(10, as_table=True), 1) ow.show() a.exec()
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 setUp(self): self.widget: OWGrangerCausality = self.create_widget(OWGrangerCausality) dataset_dir = os.path.join(os.path.dirname(__file__), "datasets") self.amzn = Timeseries.from_file(os.path.join(dataset_dir, "AMZN.tab"))[:, :-3]
def commit(self): self.Outputs.selected_features.send(self.selected_attributes or None) def on_select(self): selected_rows = self.causality_view.selectionModel().selectedRows() row_indices = [i.row() for i in selected_rows] row_indices = self.model.mapToSourceRows(row_indices) attributes = [ self.model[i][j] for i in row_indices for j in [COLUMNS.index("Series 1"), COLUMNS.index("Series 2")] ] # remove duplicated attributes - I know I could use set for this but # I want to keep the order of attributes - keeping first appearance # of an attribute and remove the rest attributes = list(dict.fromkeys(attributes)) self.selected_attributes = [self.data.domain[a] for a in attributes] self.commit() def header_click(self, _): # Store the header states sort_order = self.model.sortOrder() sort_column = self.model.sortColumn() self.sorting = (sort_column, sort_order) if __name__ == "__main__": data = Timeseries.from_file("AMZN") WidgetPreview(OWGrangerCausality).run(data)
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 on_changed(self): self.commit() def commit(self): self.Warning.no_transforms_added.clear() data = self.data if not data: self.Outputs.time_series.send(None) return if not len(self.table_model): self.Warning.no_transforms_added() self.Outputs.time_series.send(None) return ts = moving_transform(data, self.table_model, self.non_overlapping and self.fixed_wlen) self.Outputs.time_series.send(ts) if __name__ == "__main__": data = Timeseries.from_file('airpassengers') attrs = [var.name for var in data.domain.attributes] if 'Adj Close' in attrs: # Make Adjusted Close a class variable attrs.remove('Adj Close') data = Timeseries.from_table( Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) WidgetPreview(OWMovingTransform).run(data)
if var.is_continuous and var != data.time_variable ]) @Inputs.forecast def set_forecast(self, forecast, id): if forecast is not None: self.forecasts[id] = forecast else: self.forecasts.pop(id, None) # TODO: update currently shown plots if __name__ == "__main__": from AnyQt.QtWidgets import QApplication from orangecontrib.timeseries import ARIMA, VAR a = QApplication([]) ow = OWLineChart() airpassengers = Timeseries('airpassengers') ow.set_data(airpassengers), msft = airpassengers.interp() model = ARIMA((3, 1, 1)).fit(airpassengers) ow.set_forecast(model.predict(10, as_table=True), 0) model = VAR(4).fit(msft) ow.set_forecast(model.predict(10, as_table=True), 1) ow.show() a.exec()
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 seasonal_decompose(data, model='multiplicative', period=12, *, callback=None): """ Return table of decomposition components of original features and original features seasonally adjusted. Parameters ---------- data : Timeseries A table of featres to decompose/adjust. model : str {'additive', 'multiplicative'} A decompostition model. See: https://en.wikipedia.org/wiki/Decomposition_of_time_series period : int The period length of season. callback : callable Optional callback to call (with no parameters) after each iteration. Returns ------- table : Timeseries Table with columns: original series seasonally adjusted, original series' seasonal components, trend components, and residual components. """ from operator import sub, truediv from Orange.data import Domain, ContinuousVariable from orangecontrib.timeseries import Timeseries from orangecontrib.timeseries.widgets.utils import available_name import statsmodels.api as sm def _interp_trend(trend): first = next(i for i, val in enumerate(trend) if val == val) last = trend.size - 1 - next( i for i, val in enumerate(trend[::-1]) if val == val) d = 3 first_last = min(first + d, last) last_first = max(first, last - d) k, n = np.linalg.lstsq( np.column_stack( (np.arange(first, first_last), np.ones(first_last - first))), trend[first:first_last])[0] trend[:first] = np.arange(0, first) * k + n k, n = np.linalg.lstsq( np.column_stack((np.arange(last_first, last), np.ones(last - last_first))), trend[last_first:last])[0] trend[last + 1:] = np.arange(last + 1, trend.size) * k + n return trend attrs = [] X = [] recomposition = sub if model == 'additive' else truediv interp_data = data.interp() for var in data.domain.variables: decomposed = sm.tsa.seasonal_decompose(np.ravel(interp_data[:, var]), model=model, freq=period) adjusted = recomposition(decomposed.observed, decomposed.seasonal) season = decomposed.seasonal trend = _interp_trend(decomposed.trend) resid = recomposition(adjusted, trend) # Re-apply nans isnan = np.isnan(data[:, var]).ravel() adjusted[isnan] = np.nan trend[isnan] = np.nan resid[isnan] = np.nan attrs.extend( ContinuousVariable( available_name(data.domain, var.name + ' ({})'.format(transform))) for transform in ('season. adj.', 'seasonal', 'trend', 'residual')) X.extend((adjusted, season, trend, resid)) if callback: callback() ts = Timeseries.from_numpy(Domain(attrs), np.column_stack(X)) return ts
gui.checkBox(box, self, 'use_exog', 'Use exogenous (independent) variables (ARMAX)', callback=self.apply) def forecast(self, model): if self.use_exog and self.exog_data is None: return return model.predict(self.forecast_steps, exog=self.exog_data, alpha=1 - self.forecast_confint / 100, as_table=True) def create_learner(self): return ARIMA((self.p, self.d, self.q), self.use_exog) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication from Orange.data import Domain a = QApplication([]) ow = OWARIMAModel() data = Timeseries.from_file('airpassengers') domain = Domain(data.domain.attributes[:-1], data.domain.attributes[-1]) data = Timeseries.from_numpy(domain, data.X[:, :-1], data.X[:, -1]) ow.set_data(data) ow.show() a.exec()
callback=self.on_changed) gui.auto_commit(box, self, 'autoapply', 'Apply') def set_data(self, data): self.data = None if data is None else Timeseries.from_data_table(data) self.on_changed() def on_changed(self): self.commit() def commit(self): data = self.data if data is not None: data = data.copy() data.set_interpolation(self.interpolation, self.multivariate) self.send(Output.TIMESERIES, data) self.send(Output.INTERPOLATED, try_(lambda: data.interp()) or None) if __name__ == "__main__": from PyQt4.QtGui import QApplication a = QApplication([]) ow = OWInterpolate() data = Timeseries('airpassengers') ow.set_data(data) ow.show() a.exec()
def test_create_time_variable(self): table = Table("iris") time_series = Timeseries(table) id_1 = id(time_series.attributes) time_series.time_variable = time_series.domain.attributes[0] self.assertNotEqual(id_1, id(time_series.attributes))
self.Error.seasonal_decompose_fail(str(ex)) adjusted_data = None if adjusted_data is not None: ts = Timeseries(Timeseries.concatenate((data, adjusted_data))) ts.time_variable = data.time_variable else: ts = None self.Outputs.time_series.send(ts) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWSeasonalAdjustment() data = Timeseries('airpassengers') if not data.domain.class_var and 'Adj Close' in data.domain: # Make Adjusted Close a class variable attrs = [var.name for var in data.domain.attributes] attrs.remove('Adj Close') data = Timeseries( Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) ow.set_data(data) ow.show() a.exec()
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) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWAggregate() ow.set_data(Timeseries.from_file('airpassengers')) ow.show() a.exec()
return res = np.array(res, dtype=object) self.model.setHorizontalHeaderLabels(res[0, 1:].tolist()) self.model.setVerticalHeaderLabels(res[1:, 0].tolist()) self.model.wrap(res[1:, 1:].tolist()) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication from Orange.data import Domain from orangecontrib.timeseries import ARIMA, VAR a = QApplication([]) ow = OWModelEvaluation() data = Timeseries('yahoo_MSFT') # Make Adjusted Close a class variable attrs = [var.name for var in data.domain.attributes] if 'Adj Close' in attrs: attrs.remove('Adj Close') data = Timeseries( Domain(attrs, [data.domain['Adj Close']], None, source=data.domain), data) ow.set_data(data) ow.set_model(ARIMA((1, 1, 1)), 1) ow.set_model(ARIMA((2, 1, 0)), 2) # ow.set_model(ARIMA((0, 1, 1)), 3) # ow.set_model(ARIMA((4, 1, 0)), 4) ow.set_model(VAR(1), 11) ow.set_model(VAR(5), 12)
def setUp(self): self.widget = self.create_widget(OWSpiralogram) # type: OWSpiralogram self.passengers = Timeseries.from_file("airpassengers") self.philadelphia = Timeseries.from_url( 'http://datasets.orange.biolab.si/core/philadelphia-crime.csv.xz')
self.model.clear() self.Error.unexpected_error.clear() if data is None: return try: with self.progressBar() as progress: res = granger_causality(data, self.max_lag, 1 - self.confidence / 100, callback=progress.advance) res = [[lag, row, '→', col] for lag, row, col in res] except ValueError as ex: self.Error.unexpected_error(ex.args[0]) else: self.model.wrap(res) self.model.sort(0, Qt.DescendingOrder) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWGrangerCausality() data = Timeseries('yahoo_MSFT') ow.set_data(data) ow.show() a.exec()
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(M, dtype=object)) self.send('Time series', ts) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication a = QApplication([]) ow = OWAggregate() ow.set_data(Timeseries('autoroute')) ow.show() a.exec()
def setUp(self): data = Timeseries('airpassengers') data.Y[:2] = np.nan data.Y[10:15] = np.nan data.Y[-2:] = np.nan self.data = data
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) self.update_model()
import unittest import numpy as np from orangecontrib.timeseries import Timeseries, periodogram, periodogram_nonequispaced data = Timeseries.from_file('airpassengers') class TestPeriodogram(unittest.TestCase): def test_periodogram(self): periods, pgram = periodogram(data.Y) self.assertEqual(max(pgram), 1) self.assertEqual(np.round(periods[pgram == 1]), 6) def test_periodogram_nonequispaced(self): periods, pgram = periodogram_nonequispaced(data.X.ravel(), data.Y, detrend='diff') self.assertEqual(max(pgram), 1)
else: # Or make a sequence attribute one of the existing attributes # and sort all values according to it time_var = data.domain[self.selected_attr] values = Table.from_table(Domain([], [], [time_var]), source=data).metas.ravel() if np.isnan(values).any(): self.Error.nan_times(time_var.name) return ordered = np.argsort(values) if (ordered != np.arange(len(ordered))).any(): data = data[ordered] ts = Timeseries(data.domain, data) # TODO: ensure equidistant ts.time_variable = time_var self.send(Output.TIMESERIES, ts) if __name__ == "__main__": from AnyQt.QtWidgets import QApplication, QLabel a = QApplication([]) ow = OWTableToTimeseries() data = Timeseries('yahoo1') ow.set_data(data) ow.show() a.exec()