sarapy 1.3.1__py3-none-any.whl → 2.1.0__py3-none-any.whl

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.
@@ -54,7 +54,14 @@ class TimeSeriesProcessor(BaseEstimator, TransformerMixin):
54
54
  def transform(self, X: np.array):
55
55
  """Genera un array con los tiempos de operación, caminata, pico abierto y ratio_dCdP.
56
56
  Args:
57
- - X es un array de strings de forma (n, 2) donde la primera columna es el tiempo y la segunda columna es el tiempo de pico abierto (en segundos).
57
+ - X es un array de strings de forma (n, 2) donde la primera columna es el tiempo
58
+ y la segunda columna es el tiempo de pico abierto (en segundos).
59
+
60
+ Returns:
61
+ - Un array de numpy de forma (n, 4) donde la primera columna es
62
+ el tiempo de operación, la segunda columna es el tiempo de caminata,
63
+ la tercera columna es el tiempo de pico abierto y la cuarta columna es
64
+ el ratio entre el tiempo de caminata y el tiempo de pico abierto.
58
65
  """
59
66
 
60
67
  if not self.is_fitted:
@@ -66,6 +73,17 @@ class TimeSeriesProcessor(BaseEstimator, TransformerMixin):
66
73
  self._ratio_dCdP.reshape(-1,1))).round(2)
67
74
 
68
75
  def fit_transform(self, X: np.array, y=None):
76
+ """Genera un array con los tiempos de operación, caminata, pico abierto y ratio_dCdP.
77
+ Args:
78
+ - X es un array de strings de forma (n, 2) donde la primera columna es el tiempo
79
+ y la segunda columna es el tiempo de pico abierto (en segundos).
80
+
81
+ Returns:
82
+ - Un array de numpy de forma (n, 4) donde la primera columna es
83
+ el tiempo de operación, la segunda columna es el tiempo de caminata,
84
+ la tercera columna es el tiempo de pico abierto y la cuarta columna es
85
+ el ratio entre el tiempo de caminata y el tiempo de pico abierto.
86
+ """
69
87
  self.fit(X)
70
88
  return self.transform(X)
71
89
 
@@ -1,4 +1,5 @@
1
1
  import pickle
2
+ from sarapy.dataProcessing import TLMSensorDataProcessor
2
3
 
3
4
  class FertilizerTransformer:
4
5
  """
@@ -31,51 +32,37 @@ class FertilizerTransformer:
31
32
  self.fertilizer_grams = None ##cuando no se ha transformado ningún dato, se inicializa en None
32
33
 
33
34
 
34
- def transform(self, X):
35
+ def transform(self, data):
35
36
  """Transforma los datos de distorsión de fertilizante a gramos.
36
37
 
37
38
  Params:
38
- - X: Es un array con los datos de distorsión de fertilizante. La forma de X es (n,1)
39
-
40
- Ejemplo: [12. 1. 12. 0. 0. 0. 0. 0. 0. 12.]
39
+ - data: Es una lista de diccionarios (como un JSON) con los datos de telemetría.
41
40
 
42
41
  Returns:
43
42
  - 0: Array con los valores de distorsión de fertilizante transformados a gramos.
44
43
  """
45
-
46
- X_poly = self._poly_features.fit_transform(X)
44
+ tlmDataProcessor = TLMSensorDataProcessor.TLMSensorDataProcessor(data)
45
+ X = tlmDataProcessor["SC_FT",:]
46
+ X_poly = self._poly_features.fit_transform(X.reshape(-1, 1))
47
47
  self.fertilizer_grams = self._regresor.predict(X_poly)
48
48
 
49
49
  ##retorno con shape (n,)
50
50
  return self.fertilizer_grams.reshape(-1,)
51
51
 
52
52
  if __name__ == "__main__":
53
- import os
54
53
  import pandas as pd
55
- import numpy as np
54
+ import json
56
55
  from sarapy.preprocessing import TransformInputData
57
- from sarapy.mlProcessors import PlantinFMCreator
58
- import sarapy.utils.getRawOperations as getRawOperations
59
- tindata = TransformInputData.TransformInputData()
60
-
61
- ##cargo los archivos examples\2024-09-04\UPM001N\data.json y examples\2024-09-04\UPM001N\historical-data.json
62
- data_path = os.path.join(os.getcwd(), "examples\\2024-09-04\\UPM001N\\data.json")
63
- historical_data_path = os.path.join(os.getcwd(), "examples\\2024-09-04\\UPM001N\\historical-data.json")
64
- raw_data = pd.read_json(data_path, orient="records").to_dict(orient="records")
65
- raw_data2 = pd.read_json(historical_data_path, orient="records").to_dict(orient="records")
66
-
67
- raw_ops = np.array(getRawOperations.getRawOperations(raw_data, raw_data2))
68
- X = tindata.fit_transform(raw_ops) #transforma los datos de operaciones a un array de numpy
69
-
70
- from sarapy.mlProcessors import FertilizerFMCreator
71
56
 
72
- ftfmcreator = FertilizerFMCreator.FertilizerFMCreator()
73
- dst_ft = ftfmcreator.transform(X[:,2])
74
- ##convierto a int dst_ft
75
- dst_ft = dst_ft.astype(int)
57
+ historical_data_path = "examples/2025-06-21/UPM000N/historical-data.json"
58
+ with open(historical_data_path, 'r') as file:
59
+ historical_data = json.load(file)
76
60
 
77
- from sarapy.mlProcessors import FertilizerTransformer
61
+ ##cargo en un diccionario sarapy\preprocessing\telemetriaDataPosition.json
62
+ data_positions = json.load(open("sarapy/preprocessing/telemetriaDataPosition.json", 'r'))
63
+ transform_input_data = TransformInputData.TransformInputData()
64
+ transformed_data = transform_input_data.transform(historical_data)
78
65
 
79
- fertransformer = FertilizerTransformer.FertilizerTransformer(regresor_file='modelos\\regresor.pkl', poly_features_file='modelos\\poly_features.pkl')
80
- gramos = fertransformer.transform(dst_ft.reshape(-1,1))
66
+ fertransformer = FertilizerTransformer(regresor_file='modelos\\regresor.pkl', poly_features_file='modelos\\poly_features.pkl')
67
+ gramos = fertransformer.transform(transformed_data)
81
68
  print(gramos[:10])
@@ -4,9 +4,10 @@ from sklearn.base import BaseEstimator, TransformerMixin
4
4
  from sarapy.dataProcessing import TLMSensorDataProcessor, TimeSeriesProcessor, GeoProcessor
5
5
 
6
6
  class PlantinFMCreator(BaseEstimator, TransformerMixin):
7
- """La clase FMCreator se encarga de crear la Feature Matrix (FM) a partir de los datos de telemetría. Se utilizan las clases TLMSensorDataExtractor, TimeSeriesProcessor y GeoProcessor para realizar las transformaciones necesarias.
7
+ """La clase FMCreator se encarga de crear la Feature Matrix (FM) a partir de los datos de telemetría.
8
+ Se utilizan las clases TLMSensorDataProcessor, TimeSeriesProcessor y GeoProcessor para realizar las transformaciones necesarias.
8
9
 
9
- Versión 0.1.0
10
+ Versión 2.0.0
10
11
 
11
12
  En esta versión la matriz de características está formada por las siguientes variables
12
13
 
@@ -14,6 +15,7 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
14
15
  - deltaO: delta operación
15
16
  - ratio_dCdP: Ratio entre el delta de caminata y delta de pico abierto
16
17
  - distances: Distancias entre operaciones
18
+ - inest_pt: Inestabilidad del plantín
17
19
  """
18
20
 
19
21
  def __init__(self, imputeDistances = True, distanciaMedia:float = 1.8,
@@ -45,12 +47,7 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
45
47
  """Fittea el objeto
46
48
 
47
49
  Params:
48
- - X: Es un array con los datos provenientes (strings) de la base de datos histórica. La forma de X es (n,5)Las columnas de X son,
49
- - 0: tlm_spbb son los datos de telemetría.
50
- - 1: date_oprc son los datos de fecha y hora de operación.
51
- - 2: latitud de la operación
52
- - 3: longitud de la operación
53
- - 4: precision del GPS
50
+ - X: Es una lista de diccionarios (como un JSON) con los datos de telemetría.
54
51
  """
55
52
  self.is_fitted = True
56
53
 
@@ -58,12 +55,7 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
58
55
  """Transforma los datos de X en la matriz de características.
59
56
 
60
57
  Params:
61
- - X: Es un array con los datos provenientes (strings) de la base de datos histórica. La forma de X es (n,5)Las columnas de X son,
62
- - 0: tlm_spbb son los datos de telemetría.
63
- - 1: date_oprc son los datos de fecha y hora de operación.
64
- - 2: latitud de la operación
65
- - 3: longitud de la operación
66
- - 4: precision del GPS
58
+ - X: Es una lista de diccionarios (como un JSON) con los datos de telemetría.
67
59
 
68
60
  Returns:
69
61
  - 0: feature_matrix: (deltaO, ratio_dCdP, distances)
@@ -74,40 +66,35 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
74
66
  if not self.is_fitted:
75
67
  raise RuntimeError("El modelo no ha sido fitteado.")
76
68
 
77
- ##instanciamos los objetos
78
- tlmDataExtractor = TLMSensorDataProcessor.TLMSensorDataProcessor()
69
+ ##instanciamos los objetos a usar
70
+ self.tlmDataProcessor = TLMSensorDataProcessor.TLMSensorDataProcessor(X)
79
71
  timeProcessor = TimeSeriesProcessor.TimeSeriesProcessor()
72
+ tpDP = timeProcessor._dataPositions
80
73
  geoprocessor = GeoProcessor.GeoProcessor()
81
74
 
82
- tlm_spbb = X[:,0] #datos de telemería
83
- date_oprc = X[:,1].astype(int) #datos de fecha y hora de operación
84
- lats = X[:,2].astype(float) #latitudes de las operaciones
85
- longs = X[:,3].astype(float) #longitudes de las operaciones
75
+
76
+ date_oprc = self.tlmDataProcessor["date_oprc",:] #datos de fecha y hora de operación
77
+ time_ac = self.tlmDataProcessor["TIME_AC",:] #datos de fecha y hora de operación en formato timestamp
78
+ lats = self.tlmDataProcessor["latitud",:] #latitudes de las operaciones
79
+ longs = self.tlmDataProcessor["longitud",:] #longitudes de las operaciones
80
+ self.dst_pt = self.tlmDataProcessor["SC_PT",:] #distorsión del plantín
81
+ self.inest_pt = self.tlmDataProcessor["INST_PT",:] #inest
86
82
  # precitions = X[:,4].astype(float) #precision del GPS
87
83
 
88
- ##***** OBTENEMOS LOS DATOS PARA FITEAR LOS OBJETOS Y ASÍ PROCESAR LA FM *****
89
- ##obtengo las posiciones de los datos de tlmDataExtractor y timeProcessor
90
- self._tlmdeDP = tlmDataExtractor.dataPositions #posiciones de los datos transformados de tlmDataExtractor
91
- self._tpDP = timeProcessor.dataPositions #posiciones de los datos transformados de timeProcessor
92
-
93
- ##fitteamos tlmse con los datos de telemetría
94
- self._tlmExtracted = tlmDataExtractor.fit_transform(tlm_spbb)
84
+ ##***** OBTENEMOS LOS DATOS PARA FITEAR LOS OBJETOS Y ASÍ PROCESAR LA FM *****
95
85
 
96
86
  ##fitteamos timeProcessor con los datos de fecha y hora de operación y los TIMEAC
97
- timeData = np.hstack((date_oprc.reshape(-1,1),self._tlmExtracted[:,self._tlmdeDP["TIMEAC"]].reshape(-1, 1)))
87
+ timeData = np.hstack((date_oprc.reshape(-1,1),time_ac.reshape(-1, 1)))
88
+
98
89
  self._timeDeltas = timeProcessor.fit_transform(timeData)
99
90
 
100
91
  ##fitteamos geoprocessor con las latitudes y longitudes
101
- ##genero un array de puntos de la forma (n,2)
102
92
  points = np.hstack((lats.reshape(-1,1),longs.reshape(-1,1)))
103
93
  self._distances = geoprocessor.fit_transform(points)
104
94
 
105
- self.dst_pt = self._tlmExtracted[:,self._tlmdeDP["DSTRPT"]]
106
- self.inest_pt = self._tlmExtracted[:,self._tlmdeDP["INESTPT"]]
107
-
108
95
  ##armamos la feature matrix
109
- self.featureMatrix = np.vstack((self._timeDeltas[:,self._tpDP["deltaO"]],
110
- self._timeDeltas[:,self._tpDP["ratio_dCdP"]],
96
+ self.featureMatrix = np.vstack((self._timeDeltas[:,tpDP["deltaO"]],
97
+ self._timeDeltas[:,tpDP["ratio_dCdP"]],
111
98
  self._distances)).T
112
99
 
113
100
  return self.featureMatrix, self.dst_pt, self.inest_pt
@@ -116,12 +103,7 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
116
103
  """Fittea y transforma los datos de X en la matriz de características.
117
104
 
118
105
  Params:
119
- - X: Es un array con los datos provenientes (strings) de la base de datos histórica. La forma de X es (n,5)Las columnas de X son,
120
- - 0: tlm_spbb son los datos de telemetría.
121
- - 1: date_oprc son los datos de fecha y hora de operación.
122
- - 2: latitud de la operación
123
- - 3: longitud de la operación
124
- - 4: precision del GPS
106
+ - X: Es una lista de diccionarios (como un JSON) con los datos de telemetría.
125
107
 
126
108
  Returns:
127
109
  - 0: feature_matrix: (deltaO, ratio_dCdP, distances)
@@ -131,10 +113,10 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
131
113
  self.fit(X)
132
114
  return self.transform(X)
133
115
 
134
- @property
135
- def tlmExtracted(self):
136
- """Devuelve los datos de telemetría extraídos."""
137
- return self._tlmExtracted
116
+ # @property
117
+ # def tlmExtracted(self):
118
+ # """Devuelve los datos de telemetría extraídos."""
119
+ # return self.tlmExtracted
138
120
 
139
121
  @property
140
122
  def tlmdeDP(self):
@@ -158,23 +140,21 @@ class PlantinFMCreator(BaseEstimator, TransformerMixin):
158
140
 
159
141
 
160
142
  if __name__ == "__main__":
161
- import os
162
143
  import pandas as pd
163
- import numpy as np
144
+ import json
164
145
  from sarapy.preprocessing import TransformInputData
165
- from sarapy.mlProcessors import PlantinFMCreator
166
- import sarapy.utils.getRawOperations as getRawOperations
167
-
168
- fmcreator = PlantinFMCreator.PlantinFMCreator(imputeDistances=False)
169
- tindata = TransformInputData.TransformInputData()
170
146
 
171
- ##cargo los archivos examples\2024-09-04\UPM001N\data.json y examples\2024-09-04\UPM001N\historical-data.json
172
- data_path = os.path.join(os.getcwd(), "examples\\2024-09-04\\UPM001N\\data.json")
173
- historical_data_path = os.path.join(os.getcwd(), "examples\\2024-09-04\\UPM001N\\historical-data.json")
174
- raw_data = pd.read_json(data_path, orient="records").to_dict(orient="records")
175
- raw_data2 = pd.read_json(historical_data_path, orient="records").to_dict(orient="records")
147
+ historical_data_path = "examples/2025-06-21/UPM000N/historical-data.json"
148
+ with open(historical_data_path, 'r') as file:
149
+ historical_data = json.load(file)
150
+ df = pd.DataFrame(historical_data)
176
151
 
177
- raw_ops = np.array(getRawOperations.getRawOperations(raw_data, raw_data2))
178
- X = tindata.fit_transform(raw_ops)
152
+ ##cargo en un diccionario sarapy\preprocessing\telemetriaDataPosition.json
153
+ data_positions = json.load(open("sarapy/preprocessing/telemetriaDataPosition.json", 'r'))
154
+ transform_input_data = TransformInputData.TransformInputData()
155
+ X = transform_input_data.transform(historical_data)
156
+
157
+ fmcreator = PlantinFMCreator(imputeDistances=False)
179
158
 
180
- fm, dst_pt, inest_pt = fmcreator.fit_transform(X[:,2:])
159
+ fm, dst_pt, inest_pt = fmcreator.fit_transform(X)
160
+ print(fm.shape) # Debería ser (n_operaciones, 3)
@@ -10,101 +10,140 @@ class TransformInputData(BaseEstimator, TransformerMixin):
10
10
 
11
11
  def __init__(self):
12
12
  """
13
- Constructor de la clase TransformInputData.
14
-
15
- Args:
16
- - features_list: Lista con los nombres de las columnas a extraer de los datos recibidos de cada operación.
17
- """
18
- self.is_fitted = False
19
- self.positions = {"id_db_h":0,
20
- "ID_NPDP":1,
21
- "TLM_NPDP":2,
22
- "date_oprc":3,
23
- "latitud":4,
24
- "longitud":5,
25
- "Precision":6,
26
- "FR":7,
27
- "id_db_dw":8}
13
+ Inicializa la clase TransformToJson.
28
14
 
29
- def fit(self, X:np.array, y = None):
30
- """
31
- Fittea el objeto
15
+ Args:
16
+ data_positions (dict): Diccionario con las posiciones de los datos en el formato JSON. Se utiliza para identificar
17
+ la posición de cada dato en el JSON transformado. Diferentes transformadores pueden tener diferentes posiciones de datos.
32
18
  """
33
- self.is_fitted = True
19
+ # self.dataPositions = TransformInputData.data_positions # Diccionario para almacenar las posiciones de los datos
20
+ self.data_positions = { "Date_oprc": 0, "Operacion": 1, "SC_PT": 2, "DATA_PT": 3, "INST_PT": 4, "RES_PT": 5,
21
+ "CLMP_PT": 6, "SC_FT": 7, "DATA_FT": 8, "INST_FT": 9, "RES_FT": 10, "CLMP_FT": 11, "SC_GYRO_Z": 12,
22
+ "SC_GYRO_Y": 13, "SC_GYRO_X": 14, "DATA_GYRO": 15, "INST_GYRO": 16, "CLMP_GYRO": 17, "SC_ACCEL_Z": 18,
23
+ "SC_ACCEL_Y": 19, "SC_ACCEL_X": 20, "DATA_ACCEL": 21, "INST_ACCEL": 22, "CLMP_ACCEL": 23, "TIME_AC": 24,
24
+ "OPEN_AC": 25, "Longitud_N": 26, "Latitud_N": 27, "Precision_N": 28, "N_FIX": 29, "N_SIV": 30, "N_PDOP": 31,
25
+ "N_NBAT": 32, "N_SBAT": 33, "N_VBAT": 34, "N_CBAT": 35, "N_CHRG": 36, "ID_NPDP": 37, "N_MODE": 38, "N_RST": 39,
26
+ "N_FLASH": 40, "N_CLK": 41, "N_EST_GNSS": 42, "N_EST_NFC": 43, "N_EST_RF": 44, "N_EST_IMU": 45, "N_EST_BMS": 46,
27
+ "EST_CDC": 47, "N_ONLINE": 48, "N_RSSI": 49, "SEND_TRY": 50, "PMST": 51, "ID_OPRR": 52, "N_DATA_ID": 53,
28
+ "ID_GPDP": 54, "G_MODE": 55, "G_RST": 56, "G_FLASH": 57, "G_CLK": 58, "G_EST_4G": 59, "G_EST_NFC": 60,
29
+ "G_EST_IMU": 61,"G_EST_BMS": 62, "G_RSSI": 63, "G_NETWORK": 64, "G_ONLINE": 65, "G_SIGNAL": 66,
30
+ "G_MONEY": 67, "ID_CDLL": 68,"G_DATA_ID": 69, "Longitud_G": 70, "Latitud_G": 71, "Precision_G": 72,
31
+ "G_FIX": 73, "G_SIV": 74, "G_PDOP": 75, "G_NBAT": 76, "G_SBAT": 77, "G_VBAT": 78, "G_CBAT": 79, "G_CHRG": 80,
32
+ "VUX1": 81, "VUX2": 82, "VUX3": 83, "VUX4": 84, "VUX5": 85, "VUX6": 86, "VUX7": 87, "VUX8": 88,
33
+ "VUX9": 89, "VUX10": 90}
34
+ self.dataFloat = ["latitud","longitud","Longitud_N","Latitud_N","Longitud_G","Latitud_G","date_oprc","Date_oprc"]
35
+ self.dataString = ["timestamp"]
34
36
 
35
- self.newSample = np.array([[d["id_db_h"],
36
- d["ID_NPDP"],
37
- ''.join([bin(byte)[2:].zfill(8) for byte in d["TLM_NPDP"]]),
38
- int(d["date_oprc"].timestamp()),
39
- d["Latitud"],
40
- d["Longitud"],
41
- d["Precision"],
42
- d["FR"],
43
- d["id_db_dw"]] for d in X])
44
-
45
- return self
46
-
47
- def transform(self, X:np.array):
37
+ def transform(self, X):
48
38
  """
49
- Transforma los datos de entrada a un formato utilizable para procesar las operaciones.
39
+ Método para transformar los datos en formato JSON.
50
40
 
51
41
  Args:
52
- data: Es una lista de diccionario. Cada diccionario tiene los siguientes keys.
53
-
54
- Ejemplo:
55
-
56
- {
57
- "id_db_h":1, #int
58
- "ID_NPDP":"XXAA123", #string
59
- "FR": 1, #int
60
- "TLM_NPDP": b'\xfc\x01\t\t\x00\x00\x00\x98', #bytes
61
- "date_oprc":datetime.datetime(2024, 2, 16, 21, 2, 2, tzinfo=tzutc()),#datetime
62
- "Latitud":-32.145564789, #float
63
- "Longitud":-55.145564789, #float
64
- "Precision": 1000,
65
- "id_db_dw": 1 #int
66
- }
67
-
68
- NOTA: Los diccionarios de la lista tienen más datos, pero no se usan ahora.
42
+ X: Lista de diccionario. Cada diccionario tiene la forma.
43
+ Ejemplo (NOTA: El salto de línea es agregado para mejorar la legibilidad):
44
+ [
45
+ {"id": 6, "receiver_timestamp": "2025-06-21T15:51:36.527825+00:00", "timestamp": "2025-06-21T15:51:01.000002+00:00", "datum": null,
46
+ "csv_datum": "2025-06-21T15:51:01.000002+00:00,2,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-58.0321,-33.2471,
47
+ 1,0,0,0,0,0,0,0,0,0,1,1,1,0,1,1,0,0,0,0,1,0,0,1,1,0,3,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0.0000,0.0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
48
+ "longitude": null, "latitude": null, "accuracy": null, "tag_seedling": null, "tag_fertilizer": null}
49
+ ]
50
+
51
+ NOTA: Cada diccionario debe tener, o sí, los siguientes keys (además de los que ya tiene csv_datum)
52
+ - 0: id_db_h (sale de "id" dentro de los datos de entrada X)
53
+ - 1: ID_NPDP (sale de csv_datum)
54
+ - 3: date_oprc (sale de csv_datum)
55
+ - 4: latitud (sale de csv_datum)
56
+ - 5: longitud (sale de csv_datum)
57
+ - 6: precision (sale de csv_datum)
58
+ - 7: FR
59
+ - 8: id_db_dw (sale de "Operacion" dentro de csv_datum)
69
60
 
70
61
  Returns:
71
- Retorna un array de strings con la siguiente estructura
72
- - 0: id_db_h
73
- - 1: ID_NPDP
74
- - 2: TLM_NPDP
75
- - 3: date_oprc
76
- - 4: latitud
77
- - 5: longitud
78
- - 6: Precision
79
- - 7: FR
80
- - 8: id_db_dw
81
- """
82
- ##chequeamos si se ha llamado a fit(). Sino, se arroja un error
83
- if not self.is_fitted:
84
- raise ValueError("TransformInputData no ha sido fitteado. Llame a fit() previamente.")
62
+ Lista de diccionarios con los datos transformados. Básciamente se toma csv_datum y se agrega a cada uno de los diccionarios de la lista.
63
+ Para esto, se usa el diccionario `dataPositions` para identificar las posiciones y qué son cada uno de los valores dentro de `csv_datum`.
64
+ Los diccionarios dentro de la lista no tendrán csv_datum.
65
+ """
66
+ self.data_transformed = []
67
+ dict_structre = {"id_db_h":None, "id_db_dw":None, "ID_NPDP":None,
68
+ "date_oprc":None, "latitud":None, "longitud":None,
69
+ "precision":None, "FR":None, "timestamp": None}
85
70
 
86
- return self.newSample
87
-
88
- def fit_transform(self, X:np.array, y=None):
89
- self.fit(X)
90
- return self.transform(X)
71
+ ##agrego los keys que están en dataPositions con valores None
72
+ for key in self.data_positions.keys():
73
+ dict_structre[key] = None
74
+
75
+
76
+ for row in X:
77
+ # Crear un diccionario para almacenar los datos transformados
78
+ data_dict = dict_structre.copy()
79
+ # Asignar los valores de csv_datum a las posiciones correspondientes
80
+ csv_datum = row.get("csv_datum", "")
81
+ if csv_datum:
82
+ values = csv_datum.split(',')
83
+ for key, pos in self.data_positions.items():
84
+ if pos < len(values):
85
+ data_dict[key] = values[pos]
86
+ else:
87
+ data_dict[key] = None
88
+
89
+ data_dict["id_db_h"] = row.get("id", None)
90
+ data_dict["id_db_dw"] = data_dict.get("Operacion", None)
91
+ data_dict["ID_NPDP"] = data_dict.get("ID_NPDP", None)
92
+ ##convierto Date_oprc a un objeto datetime y paso a timestamp
93
+ date_oprc = data_dict.get("Date_oprc", None)
94
+ if date_oprc:
95
+ try:
96
+ from dateutil import parser
97
+ data_dict["date_oprc"] = parser.isoparse(date_oprc).timestamp()
98
+ except Exception as e:
99
+ print(f"Error parsing date_oprc: {e}")
100
+ data_dict["date_oprc"] = None
101
+ else:
102
+ data_dict["date_oprc"] = None
103
+ data_dict["latitud"] = data_dict.get("Latitud_N", None)
104
+ data_dict["longitud"] = data_dict.get("Longitud_N", None)
105
+ data_dict["precision"] = data_dict.get("Precision_N", None)
106
+ data_dict["Date_oprc"] = data_dict.get("date_oprc", None)
107
+ data_dict["latitud"] = data_dict.get("Latitud_N", None)
108
+ data_dict["longitud"] = data_dict.get("Longitud_N", None)
109
+ data_dict["timestamp"] = row.get("timestamp", None)
110
+ # data_dict["FR"] = row.get("tag_fertilizer", None)
111
+
112
+ # Agregar el diccionario transformado a la lista
113
+ self.data_transformed.append(data_dict)
114
+
115
+ ##convierto los datos de self.dataFloat a float y el resto a int
116
+ for data in self.data_transformed:
117
+ for key, value in data.items():
118
+ if key in self.dataFloat:
119
+ try:
120
+ data[key] = float(value) if value else None
121
+ except ValueError:
122
+ data[key] = None
123
+ elif key in self.dataString:
124
+ try:
125
+ data[key] = str(value) if value else None
126
+ except ValueError:
127
+ data[key] = None
128
+ else:
129
+ try:
130
+ data[key] = int(value) if value else None
131
+ except ValueError:
132
+ data[key] = None
133
+
134
+ return self.data_transformed
91
135
 
92
136
  if __name__ == "__main__":
93
137
  import pandas as pd
94
- import numpy as np
95
- import os
96
- from sarapy.utils.getRawOperations import getRawOperations
97
-
98
- # features=["id_db_h","ID_NPDP","TLM_NPDP","date_oprc","latitud","longitud","Precision","FR","id_db_dw",
99
- # "INESTPT","INESTFT"]
100
-
101
- transform_input_data = TransformInputData()
102
-
103
- #cargo "examples\\2024-05-30\\UPM007N\\data.json"
104
- data = pd.read_json("examples\\2024-05-30\\UPM007N\\data.json").to_dict(orient="records")
105
- historical_data = pd.read_json("examples\\2024-05-30\\UPM007N\\historical-data.json").to_dict(orient="records")
138
+ import json
106
139
 
107
- ppk_results = getRawOperations(data,historical_data)
140
+ historical_data_path = "examples/2025-06-21/UPM000N/historical-data.json"
141
+ with open(historical_data_path, 'r') as file:
142
+ historical_data = json.load(file)
143
+ df = pd.DataFrame(historical_data)
108
144
 
109
- X = np.array(ppk_results)
110
- print(transform_input_data.fit_transform(X))
145
+ ##cargo en un diccionario sarapy\preprocessing\telemetriaDataPosition.json
146
+ data_positions = json.load(open("sarapy/preprocessing/telemetriaDataPosition.json", 'r'))
147
+ transform_input_data = TransformInputData()
148
+ transformed_data = transform_input_data.transform(historical_data)
149
+ print(transformed_data[-1])
@@ -10,14 +10,11 @@ class TransformToOutputData(BaseEstimator, TransformerMixin):
10
10
  - dataToTransform: array con los datos de las operaciones clasificadas.
11
11
  Actualmente el array de dataToTransform es de (n,5) con las columnas siguientes
12
12
 
13
- - 0: id_db_h
14
- - 1: id_db_dw
15
- - 2: tag_seedling
16
- - 3: tag_fertilizer
17
- - 4: date_oprc
13
+ - 0: timestamps
14
+ - 1: tag_seedling
15
+ - 2: tag_fertilizer
18
16
  Returns:
19
17
  Retorna una lista de diccionarios con la siguiente estructura
20
- [{"id_db_h", },]
21
18
  """
22
19
 
23
20
  def __init__(self):
@@ -28,11 +25,6 @@ class TransformToOutputData(BaseEstimator, TransformerMixin):
28
25
  - features_list: Lista con los nombres de las columnas a extraer de los datos recibidos de cada operación.
29
26
  """
30
27
  self.is_fitted = False
31
- self.positions = {"id_db_h":0,
32
- "id_db_dw":1,
33
- "tag_seedling":2,
34
- "tag_fertilizer":3,
35
- "date_oprc":4}
36
28
 
37
29
  def fit(self, X:np.array, y = None):
38
30
  """
@@ -40,21 +32,16 @@ class TransformToOutputData(BaseEstimator, TransformerMixin):
40
32
  - X: array con los datos de las operaciones clasificadas.
41
33
  Actualmente el array de dataToTransform es de (n,5) con las columnas siguientes
42
34
 
43
- - 0: id_db_h
44
- - 1: id_db_dw
45
- - 2: tag_seedling
46
- - 3: tag_fertilizer
47
- - 4: date_oprc
35
+ - 0: timestamps
36
+ - 1: tag_seedling
37
+ - 2: tag_fertilizer
48
38
  """
49
39
  self.is_fitted = True
50
- keys = ["id_db_h", "id_db_dw", "tag_seedling", "tag_fertilizer", "date_oprc"]
40
+ keys = ["timestamps","tag_seedling", "tag_fertilizer"]
51
41
  self.temp_df = pd.DataFrame(X, columns = keys)
52
-
53
- date_data = X[:,4].astype(int)
54
- date_oprc = np.array([datetime.datetime.fromtimestamp(date, datetime.timezone.utc) for date in date_data])
55
- self.temp_df.loc[:,"date_oprc"] = date_oprc.flatten()
56
- ##convierto las columnas "id_db_h", "id_db_dw", "tag_seedling" a int
57
- for col in ["id_db_h", "id_db_dw", "tag_seedling"]:
42
+
43
+ ##convierto las columnas "timestamps", "tag_seedling" a int
44
+ for col in ["tag_seedling"]:
58
45
  self.temp_df[col] = self.temp_df[col].astype(float).astype(int)
59
46
  ##convierto la columna "tag_fertilizer" a float de y redondeo a 3 decimales
60
47
  self.temp_df["tag_fertilizer"] = self.temp_df["tag_fertilizer"].astype(float).round(3)
@@ -67,11 +54,9 @@ class TransformToOutputData(BaseEstimator, TransformerMixin):
67
54
  - X: array con los datos de las operaciones clasificadas.
68
55
  Actualmente el array de dataToTransform es de (n,5) con las columnas siguientes
69
56
 
70
- - 0: id_db_h
71
- - 1: id_db_dw
72
- - 2: tag_seedling
73
- - 3: tag_fertilizer
74
- - 4: date_oprc
57
+ - 0: timestamps
58
+ - 1: tag_seedling
59
+ - 2: tag_fertilizer
75
60
  Returns:
76
61
  Retorna una lista de diccionarios donde cada diccionario contiene los datos de una operación para los campos mencionados anteriormente.
77
62
  """
@@ -84,11 +69,9 @@ class TransformToOutputData(BaseEstimator, TransformerMixin):
84
69
  - X: array con los datos de las operaciones clasificadas.
85
70
  Actualmente el array de dataToTransform es de (n,5) con las columnas siguientes
86
71
 
87
- - 0: id_db_h
88
- - 1: id_db_dw
89
- - 2: tag_seedling
90
- - 3: tag_fertilizer
91
- - 4: date_oprc
72
+ - 0: timestamps
73
+ - 1: tag_seedling
74
+ - 2: tag_fertilizer
92
75
  Returns:
93
76
  Retorna una lista de diccionarios donde cada diccionario contiene los datos de una operación para los campos mencionados anteriormente.
94
77
  """
@@ -0,0 +1 @@
1
+ # from stats.stats import *