TimeFeatures 1.0.10__tar.gz → 1.0.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/PKG-INFO +1 -1
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/TimeFeatures.egg-info/PKG-INFO +1 -1
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/TimeFeatures.egg-info/SOURCES.txt +2 -2
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/setup.py +1 -1
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/owsavetodb.py +11 -4
- TimeFeatures-1.0.10/timefeatures/widgets/owtimefeatureconstructor.py → TimeFeatures-1.0.12/timefeatures/widgets/owtimefeaturesconstructor.py +53 -8
- TimeFeatures-1.0.10/timefeatures/widgets/owtfgraphgenerator.py → TimeFeatures-1.0.12/timefeatures/widgets/owvardependencygraph.py +78 -5
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/LICENSE +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/README.md +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/TimeFeatures.egg-info/dependency_links.txt +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/TimeFeatures.egg-info/entry_points.txt +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/TimeFeatures.egg-info/top_level.txt +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/setup.cfg +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/__init__.py +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/icons/graphgenerator.svg +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/icons/savedatadb.svg +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/icons/timefeature-xs.svg +0 -0
- {TimeFeatures-1.0.10 → TimeFeatures-1.0.12}/timefeatures/widgets/icons/timefeature.svg +0 -0
|
@@ -9,8 +9,8 @@ TimeFeatures.egg-info/entry_points.txt
|
|
|
9
9
|
TimeFeatures.egg-info/top_level.txt
|
|
10
10
|
timefeatures/widgets/__init__.py
|
|
11
11
|
timefeatures/widgets/owsavetodb.py
|
|
12
|
-
timefeatures/widgets/
|
|
13
|
-
timefeatures/widgets/
|
|
12
|
+
timefeatures/widgets/owtimefeaturesconstructor.py
|
|
13
|
+
timefeatures/widgets/owvardependencygraph.py
|
|
14
14
|
timefeatures/widgets/icons/graphgenerator.svg
|
|
15
15
|
timefeatures/widgets/icons/savedatadb.svg
|
|
16
16
|
timefeatures/widgets/icons/timefeature-xs.svg
|
|
@@ -21,7 +21,7 @@ setup(name="TimeFeatures",
|
|
|
21
21
|
packages=["timefeatures.widgets"],
|
|
22
22
|
package_data={"timefeatures.widgets": ["icons/*.svg", "icons/*.png"]},
|
|
23
23
|
entry_points={"orange.widgets": "Time-Features = timefeatures.widgets"},
|
|
24
|
-
version="1.0.
|
|
24
|
+
version="1.0.12",
|
|
25
25
|
author="Alejandro Rivas García",
|
|
26
26
|
author_email="alejandrorivasgarcia@gmail.com",
|
|
27
27
|
keywords=[
|
|
@@ -46,7 +46,7 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
46
46
|
name = "Save to DB"
|
|
47
47
|
description = "Save a dataset into a DB."
|
|
48
48
|
icon = "icons/savedatadb.svg"
|
|
49
|
-
priority =
|
|
49
|
+
priority = 2241
|
|
50
50
|
keywords = "sql table, save, data, db, dataset"
|
|
51
51
|
|
|
52
52
|
class Inputs:
|
|
@@ -169,7 +169,8 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
169
169
|
datetime TIMESTAMP NOT NULL,
|
|
170
170
|
rows INT NOT NULL,
|
|
171
171
|
cols INT NOT NULL,
|
|
172
|
-
class VARCHAR(30)
|
|
172
|
+
class VARCHAR(30),
|
|
173
|
+
class_name VARCHAR(30)
|
|
173
174
|
)
|
|
174
175
|
"""
|
|
175
176
|
try:
|
|
@@ -257,9 +258,15 @@ class owsavetodb(OWBaseSql, OWWidget):
|
|
|
257
258
|
self.Error.connection("Host and database fields must be filled.")
|
|
258
259
|
else:
|
|
259
260
|
self.create_master_table()
|
|
260
|
-
|
|
261
|
+
|
|
262
|
+
if self.data.domain.class_var:
|
|
263
|
+
class_name = self.data.domain.class_var.name
|
|
264
|
+
else:
|
|
265
|
+
class_name = None
|
|
266
|
+
|
|
267
|
+
query = "INSERT INTO public.datasets (name, datetime, rows, cols, class, class_name) VALUES ('" + self.tableName.text().lower() + "','" + datetime.now().strftime(
|
|
261
268
|
'%Y-%m-%d %H:%M:%S') + "','" + str(self.rows) + "','" + str(self.cols) + "','" + str(
|
|
262
|
-
self.target) + "');"
|
|
269
|
+
self.target) + "','" + str(class_name) + "');"
|
|
263
270
|
|
|
264
271
|
try:
|
|
265
272
|
with self.backend.execute_sql_query(query):
|
|
@@ -809,20 +809,21 @@ class FeatureConstructorHandler(DomainContextHandler):
|
|
|
809
809
|
return True
|
|
810
810
|
|
|
811
811
|
|
|
812
|
-
class
|
|
813
|
-
name = "Time
|
|
812
|
+
class owtimefeaturesconstructor(OWWidget, ConcurrentWidgetMixin):
|
|
813
|
+
name = "Time Features Constructor"
|
|
814
814
|
description = "Construct new time features (data columns) from a set of " \
|
|
815
815
|
"existing features in the input dataset."
|
|
816
816
|
icon = "icons/timefeature.svg"
|
|
817
|
-
keywords = "time
|
|
818
|
-
priority =
|
|
817
|
+
keywords = "time features constructor, function, time, constructor, features"
|
|
818
|
+
priority = 2239
|
|
819
819
|
|
|
820
820
|
class Inputs:
|
|
821
821
|
data = Input("Data", Orange.data.Table)
|
|
822
|
+
expressions = Input("Variable Definitions", Orange.data.Table)
|
|
822
823
|
|
|
823
824
|
class Outputs:
|
|
824
825
|
data = Output("Data", Orange.data.Table)
|
|
825
|
-
expressions = Output("
|
|
826
|
+
expressions = Output("Variable Definitions", Orange.data.Table)
|
|
826
827
|
|
|
827
828
|
want_main_area = False
|
|
828
829
|
|
|
@@ -847,11 +848,13 @@ class owtimefeatureconstructor(OWWidget, ConcurrentWidgetMixin):
|
|
|
847
848
|
class Warning(OWWidget.Warning):
|
|
848
849
|
renamed_var = Msg("Recently added variable has been renamed, "
|
|
849
850
|
"to avoid duplicates.\n")
|
|
851
|
+
table_warning = Msg("You need a configuration table (Variable-Expression).")
|
|
850
852
|
|
|
851
853
|
def __init__(self):
|
|
852
854
|
super().__init__()
|
|
853
855
|
ConcurrentWidgetMixin.__init__(self)
|
|
854
856
|
self.data = None
|
|
857
|
+
self.expressions = None
|
|
855
858
|
self.dataOriginal = None
|
|
856
859
|
self.editors = {}
|
|
857
860
|
|
|
@@ -1022,7 +1025,6 @@ class owtimefeatureconstructor(OWWidget, ConcurrentWidgetMixin):
|
|
|
1022
1025
|
|
|
1023
1026
|
self.apply()
|
|
1024
1027
|
|
|
1025
|
-
|
|
1026
1028
|
def _on_selectedVariableChanged(self, selected, *_):
|
|
1027
1029
|
index = selected_row(self.featureview)
|
|
1028
1030
|
if index is not None:
|
|
@@ -1102,6 +1104,35 @@ class owtimefeatureconstructor(OWWidget, ConcurrentWidgetMixin):
|
|
|
1102
1104
|
self.fix_button.setHidden(not self.expressions_with_values)
|
|
1103
1105
|
self.editorstack.setEnabled(self.currentIndex >= 0)
|
|
1104
1106
|
|
|
1107
|
+
@Inputs.expressions
|
|
1108
|
+
@check_sql_input
|
|
1109
|
+
def setExpressions(self, expressions=None):
|
|
1110
|
+
|
|
1111
|
+
self.expressions = expressions
|
|
1112
|
+
|
|
1113
|
+
if self.expressions is None:
|
|
1114
|
+
self.Warning.clear()
|
|
1115
|
+
self.Error.transform_error.clear()
|
|
1116
|
+
|
|
1117
|
+
if self.data is not None and self.expressions is not None:
|
|
1118
|
+
if self.expressions is not None:
|
|
1119
|
+
if len(self.expressions.domain) >= 2 and (
|
|
1120
|
+
self.expressions.domain[0].name != "Variable" or self.expressions.domain[1].name != "Expression"):
|
|
1121
|
+
self.Warning.table_warning()
|
|
1122
|
+
else:
|
|
1123
|
+
self.Error.transform_error.clear()
|
|
1124
|
+
for datos in reversed(self.expressions):
|
|
1125
|
+
if not math.isnan(datos[1]) and str(datos[1]) != "NaN":
|
|
1126
|
+
desc = ContinuousDescriptor(
|
|
1127
|
+
name=str(datos[0]),
|
|
1128
|
+
expression=str(datos[1]),
|
|
1129
|
+
meta=False,
|
|
1130
|
+
number_of_decimals=3,
|
|
1131
|
+
)
|
|
1132
|
+
self.addFeature(desc)
|
|
1133
|
+
else:
|
|
1134
|
+
self.Error.transform_error("There is not data input.")
|
|
1135
|
+
|
|
1105
1136
|
def handleNewSignals(self):
|
|
1106
1137
|
if self.data is not None:
|
|
1107
1138
|
self.apply()
|
|
@@ -1187,6 +1218,14 @@ class owtimefeatureconstructor(OWWidget, ConcurrentWidgetMixin):
|
|
|
1187
1218
|
desc = self._validate_descriptors(desc)
|
|
1188
1219
|
self.start(run, self.data, desc, self.expressions_with_values)
|
|
1189
1220
|
|
|
1221
|
+
'''
|
|
1222
|
+
INTENTO DE PODER USAR VARIABLES NO CONTENIDAS EN EL DATASET ORIGINAL.
|
|
1223
|
+
|
|
1224
|
+
desc = list(self.featuremodel)
|
|
1225
|
+
for d in desc:
|
|
1226
|
+
self.start(run, self.data, self._validate_descriptors(d), self.expressions_with_values)'''
|
|
1227
|
+
|
|
1228
|
+
|
|
1190
1229
|
def on_done(self, result: "Result") -> None:
|
|
1191
1230
|
data, attrs, desc = result.data, result.attributes, result.desc
|
|
1192
1231
|
disc_attrs_not_ok = self.check_attrs_values(
|
|
@@ -1360,6 +1399,7 @@ class Result:
|
|
|
1360
1399
|
def run(data: Table, desc, use_values, task: TaskState) -> Result:
|
|
1361
1400
|
if task.is_interruption_requested():
|
|
1362
1401
|
raise CancelledError # pragma: no cover
|
|
1402
|
+
|
|
1363
1403
|
new_variables, new_metas = construct_variables(desc, data, use_values)
|
|
1364
1404
|
# Explicit cancellation point after `construct_variables` which can
|
|
1365
1405
|
# already run `compute_value`.
|
|
@@ -1373,10 +1413,14 @@ def run(data: Table, desc, use_values, task: TaskState) -> Result:
|
|
|
1373
1413
|
try:
|
|
1374
1414
|
for variable in new_variables:
|
|
1375
1415
|
variable.compute_value.mask_exceptions = False
|
|
1376
|
-
|
|
1416
|
+
try:
|
|
1417
|
+
data = data.transform(new_domain)
|
|
1418
|
+
except:
|
|
1419
|
+
raise TypeError("One or more variables were not found.")
|
|
1377
1420
|
finally:
|
|
1378
1421
|
for variable in new_variables:
|
|
1379
1422
|
variable.compute_value.mask_exceptions = True
|
|
1423
|
+
|
|
1380
1424
|
return Result(data, new_variables, new_metas, desc)
|
|
1381
1425
|
|
|
1382
1426
|
|
|
@@ -1455,6 +1499,7 @@ def validate_exp(exp):
|
|
|
1455
1499
|
|
|
1456
1500
|
def construct_variables(descriptions, data, use_values=False):
|
|
1457
1501
|
# subs
|
|
1502
|
+
|
|
1458
1503
|
variables = []
|
|
1459
1504
|
metas = []
|
|
1460
1505
|
source_vars = data.domain.variables + data.domain.metas
|
|
@@ -1814,4 +1859,4 @@ class FeatureFunc:
|
|
|
1814
1859
|
|
|
1815
1860
|
|
|
1816
1861
|
if __name__ == "__main__": # pragma: no cover
|
|
1817
|
-
WidgetPreview(
|
|
1862
|
+
WidgetPreview(owtimefeaturesconstructor).run(Orange.data.Table("iris"))
|
|
@@ -17,6 +17,72 @@ from PyQt5.QtWidgets import QPushButton, QVBoxLayout, QHBoxLayout
|
|
|
17
17
|
from orangecontrib.network import Network
|
|
18
18
|
from orangewidget.utils.signals import Input
|
|
19
19
|
|
|
20
|
+
'''
|
|
21
|
+
|
|
22
|
+
CALCULO DE PONDERACIONES PARA LOS PESOS DE LAS ARISTAS.
|
|
23
|
+
|
|
24
|
+
def calculate_weight(expression):
|
|
25
|
+
# Encontrar todas las coincidencias con las funciones temporales y almacenarlas
|
|
26
|
+
matches_shift = list(re.finditer(r'shift\(([^,]+),([-+]?\d+)\)', expression))
|
|
27
|
+
matches_sum = list(re.finditer(r'sum\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
28
|
+
matches_mean = list(re.finditer(r'mean\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
29
|
+
matches_count = list(re.finditer(r'count\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
30
|
+
matches_min = list(re.finditer(r'min\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
31
|
+
matches_max = list(re.finditer(r'max\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
32
|
+
matches_sd = list(re.finditer(r'sd\(([^,]+),([-+]?\d+),([-+]?\d+)\)', expression))
|
|
33
|
+
|
|
34
|
+
valores = {}
|
|
35
|
+
|
|
36
|
+
# Iterar sobre todas las coincidencias de shift y cambiar la expresión
|
|
37
|
+
for match in matches_shift:
|
|
38
|
+
variable_name = match.group(1)
|
|
39
|
+
shift_value = match.group(2)
|
|
40
|
+
|
|
41
|
+
valores[variable_name] = -abs(int(shift_value))
|
|
42
|
+
|
|
43
|
+
for match in matches_sum:
|
|
44
|
+
variable_name = match.group(1)
|
|
45
|
+
sum_value1 = match.group(2)
|
|
46
|
+
sum_value2 = match.group(3)
|
|
47
|
+
|
|
48
|
+
valores[variable_name] = -max(abs(int(sum_value1)), abs(int(sum_value2)))
|
|
49
|
+
|
|
50
|
+
for match in matches_mean:
|
|
51
|
+
variable_name = match.group(1)
|
|
52
|
+
mean_value1 = match.group(2)
|
|
53
|
+
mean_value2 = match.group(3)
|
|
54
|
+
|
|
55
|
+
valores[variable_name] = -max(abs(int(mean_value1)), abs(int(mean_value2)))
|
|
56
|
+
|
|
57
|
+
for match in matches_count:
|
|
58
|
+
variable_name = match.group(1)
|
|
59
|
+
count_value1 = match.group(2)
|
|
60
|
+
count_value2 = match.group(3)
|
|
61
|
+
|
|
62
|
+
valores[variable_name] = -max(abs(int(count_value1)), abs(int(count_value2)))
|
|
63
|
+
|
|
64
|
+
for match in matches_min:
|
|
65
|
+
variable_name = match.group(1)
|
|
66
|
+
min_value1 = match.group(2)
|
|
67
|
+
min_value2 = match.group(3)
|
|
68
|
+
|
|
69
|
+
valores[variable_name] = -max(abs(int(min_value1)), abs(int(min_value2)))
|
|
70
|
+
|
|
71
|
+
for match in matches_max:
|
|
72
|
+
variable_name = match.group(1)
|
|
73
|
+
max_value1 = match.group(2)
|
|
74
|
+
max_value2 = match.group(3)
|
|
75
|
+
|
|
76
|
+
valores[variable_name] = -max(abs(int(max_value1)), abs(int(max_value2)))
|
|
77
|
+
|
|
78
|
+
for match in matches_sd:
|
|
79
|
+
variable_name = match.group(1)
|
|
80
|
+
sd_value1 = match.group(2)
|
|
81
|
+
sd_value2 = match.group(3)
|
|
82
|
+
|
|
83
|
+
valores[variable_name] = -max(abs(int(sd_value1)), abs(int(sd_value2)))
|
|
84
|
+
|
|
85
|
+
return valores.values()'''
|
|
20
86
|
|
|
21
87
|
def from_row_col(f):
|
|
22
88
|
@wraps(f)
|
|
@@ -34,12 +100,16 @@ def from_row_col(f):
|
|
|
34
100
|
expresion_regular = r'\b(' + '|'.join(map(re.escape, variables)) + r')\b'
|
|
35
101
|
|
|
36
102
|
relaciones = {}
|
|
103
|
+
# edge_weights = []
|
|
37
104
|
|
|
38
105
|
for datos in data:
|
|
39
106
|
variable = str(datos[0])
|
|
40
107
|
variable = variable.replace(" ", "_").replace("-", "_")
|
|
41
108
|
if not math.isnan(datos[1]) and str(datos[1]) != "NaN":
|
|
42
109
|
tipo_var.append(0)
|
|
110
|
+
# edge_weights_exp = calculate_weight(str(datos[1]))
|
|
111
|
+
# for weight in edge_weights_exp:
|
|
112
|
+
# edge_weights.append(int(weight))
|
|
43
113
|
else:
|
|
44
114
|
tipo_var.append(1)
|
|
45
115
|
relaciones[variable] = []
|
|
@@ -63,7 +133,10 @@ def from_row_col(f):
|
|
|
63
133
|
|
|
64
134
|
tipo_var_reshaped = np.array(tipo_var).reshape(-1, 1)
|
|
65
135
|
|
|
136
|
+
# np_edge_weights = np.array(edge_weights)
|
|
137
|
+
|
|
66
138
|
n = len(relaciones)
|
|
139
|
+
# edges = sp.csr_matrix((np_edge_weights, (row_edges, col_edges)), shape=(n, n))
|
|
67
140
|
edges = sp.csr_matrix((np.ones(len(row_edges)), (row_edges, col_edges)), shape=(n, n))
|
|
68
141
|
return Network(range(n), edges, name=f"{f.__name__}{args}"), nombres_variables, tipo_var_reshaped
|
|
69
142
|
|
|
@@ -75,11 +148,11 @@ def grafo(data=None):
|
|
|
75
148
|
return data
|
|
76
149
|
|
|
77
150
|
|
|
78
|
-
class
|
|
79
|
-
name = "
|
|
151
|
+
class owvardependencygraph(OWWidget, ConcurrentWidgetMixin):
|
|
152
|
+
name = "Variable Dependency Graph"
|
|
80
153
|
description = "Construct a graph with all the conexions between the variables"
|
|
81
154
|
icon = "icons/graphgenerator.svg"
|
|
82
|
-
keywords = "
|
|
155
|
+
keywords = "variable dependency graph, function, graph, dependency, variable"
|
|
83
156
|
priority = 2240
|
|
84
157
|
|
|
85
158
|
GRAPH_TYPES = (
|
|
@@ -97,7 +170,7 @@ class owtfgraphgenerator(OWWidget, ConcurrentWidgetMixin):
|
|
|
97
170
|
generation_error = Msg("{}")
|
|
98
171
|
|
|
99
172
|
class Inputs:
|
|
100
|
-
data = Input("
|
|
173
|
+
data = Input("Variable Definitions", Orange.data.Table)
|
|
101
174
|
|
|
102
175
|
class Outputs:
|
|
103
176
|
network = Output("Network", Network)
|
|
@@ -120,7 +193,7 @@ class owtfgraphgenerator(OWWidget, ConcurrentWidgetMixin):
|
|
|
120
193
|
buttonlayout.setContentsMargins(0, 0, 0, 0)
|
|
121
194
|
|
|
122
195
|
self.btn_generate = QPushButton(
|
|
123
|
-
"
|
|
196
|
+
"Generate", toolTip="Generate dependency graph.",
|
|
124
197
|
minimumWidth=10
|
|
125
198
|
)
|
|
126
199
|
self.btn_generate.clicked.connect(self.generate)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|