diff --git a/spatio_temporal_dataset/coordinates/abstract_coordinates.py b/spatio_temporal_dataset/coordinates/abstract_coordinates.py index 9c43045068e599e24a03af4a4f25818d93d95aee..4705d7d02ee3b897104eec623b4c84cfd10880ba 100644 --- a/spatio_temporal_dataset/coordinates/abstract_coordinates.py +++ b/spatio_temporal_dataset/coordinates/abstract_coordinates.py @@ -168,6 +168,9 @@ class AbstractCoordinates(object): else: return self.df_coordinates(split).loc[:, self.coordinates_spatial_names].drop_duplicates() + def spatial_index(self, split: Split = Split.all) -> pd.Index: + return self.df_spatial_coordinates(split).index + # Temporal attributes @property diff --git a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py index 478836829f87882ac9c712794d0117aa0e76bd27..c0ff737ea5a85c4d9930eaeea3949ece3f5dcff6 100644 --- a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py +++ b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/abstract_spatio_temporal_coordinates.py @@ -17,12 +17,15 @@ class AbstractSpatioTemporalCoordinates(AbstractCoordinates): return super().from_df_and_slicer(df, SpatioTemporalSlicer, train_split_ratio) @classmethod - def generate_df_spatio_temporal(cls, df_spatial, nb_steps): - # df_temporal = ConsecutiveTemporalCoordinates.df_temporal(nb_temporal_steps=nb_temporal_steps) + def from_df_spatial_and_nb_steps(cls, df_spatial, nb_steps, train_split_ratio: float = None, start=0): df_time_steps = [] + index_type = type(df_spatial.index[0]) for t in range(nb_steps): df_time_step = df_spatial.copy() - df_time_step[cls.COORDINATE_T] = t + df_time_step[cls.COORDINATE_T] = start + t + index_suffix = index_type(t + len(df_spatial)) + time_step_index = [i + index_suffix for i in df_spatial.index] if t > 0 else df_spatial.index + df_time_step.index = time_step_index df_time_steps.append(df_time_step) - df_time_steps = pd.concat(df_time_steps, ignore_index=True) - return df_time_steps \ No newline at end of file + df_time_steps = pd.concat(df_time_steps) + return cls.from_df(df=df_time_steps, train_split_ratio=train_split_ratio) diff --git a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/generated_spatio_temporal_coordinates.py b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/generated_spatio_temporal_coordinates.py index 9d6ba771f09a1f65773c6e38e138ec520e7542d3..b29738fc6377a453a9f381c50811511822530a54 100644 --- a/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/generated_spatio_temporal_coordinates.py +++ b/spatio_temporal_dataset/coordinates/spatio_temporal_coordinates/generated_spatio_temporal_coordinates.py @@ -15,8 +15,7 @@ class GeneratedSpatioTemporalCoordinates(AbstractSpatioTemporalCoordinates): assert cls.SPATIAL_COORDINATES_CLASS is not None assert hasattr(cls.SPATIAL_COORDINATES_CLASS, 'df_spatial') df_spatial = cls.SPATIAL_COORDINATES_CLASS.df_spatial(nb_points=nb_points) - df_time_steps = cls.generate_df_spatio_temporal(df_spatial, nb_steps) - return cls.from_df(df=df_time_steps, train_split_ratio=train_split_ratio) + return cls.from_df_spatial_and_nb_steps(df_spatial, nb_steps, train_split_ratio) class UniformSpatioTemporalCoordinates(GeneratedSpatioTemporalCoordinates): diff --git a/test/test_spatio_temporal_dataset/test_coordinates.py b/test/test_spatio_temporal_dataset/test_coordinates.py index baf51fc904c07fc9c7fe66a82f1ed383adc20308..0fbe5007a088ae406585e2edb55282e8c88e48aa 100644 --- a/test/test_spatio_temporal_dataset/test_coordinates.py +++ b/test/test_spatio_temporal_dataset/test_coordinates.py @@ -4,8 +4,9 @@ from collections import Counter, OrderedDict from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates from spatio_temporal_dataset.coordinates.spatio_temporal_coordinates.generated_spatio_temporal_coordinates import \ - UniformSpatioTemporalCoordinates -from spatio_temporal_dataset.coordinates.spatial_coordinates.coordinates_1D import UniformSpatialCoordinates + UniformSpatioTemporalCoordinates, GeneratedSpatioTemporalCoordinates +from spatio_temporal_dataset.coordinates.spatial_coordinates.coordinates_1D import UniformSpatialCoordinates, \ + LinSpaceSpatialCoordinates from spatio_temporal_dataset.coordinates.spatial_coordinates.alps_station_2D_coordinates import \ AlpsStation2DCoordinatesBetweenZeroAndOne from spatio_temporal_dataset.coordinates.spatial_coordinates.alps_station_3D_coordinates import \ @@ -52,6 +53,23 @@ class SpatioTemporalCoordinates(unittest.TestCase): good_count = c == Counter([2, 2, 2, 2]) or c == Counter([0, 0, 4, 4]) self.assertTrue(good_count) + def test_unique_spatio_temporal_index_and_matching_spatial_index(self): + spatial_coordinates = LinSpaceSpatialCoordinates.from_nb_points(self.nb_points) + spatial_indexes = [[10, 11, 12, 13], ['a', 'b', 'c', 'd']] + for spatial_index in spatial_indexes: + spatial_coordinates.df_all_coordinates.index = spatial_index + df_spatial = spatial_coordinates.df_spatial_coordinates() + coordinates = GeneratedSpatioTemporalCoordinates.from_df_spatial_and_nb_steps(df_spatial=df_spatial, + nb_steps=self.nb_steps) + + # the uniqueness of each spatio temporal index is not garanteed by the current algo + # it will work in classical cases, and raise an assert when uniqueness is needed (when using a slicer) + index1 = pd.Series(spatial_coordinates.spatial_index()) + index2 = pd.Series(coordinates.spatial_index()) + ind = index1 != index2 # type: pd.Series + self.assertEqual(sum(ind), 0, msg="spatial_coordinates:\n{} \n!= spatio_temporal_coordinates \n{}". + format(index1.loc[ind], index2.loc[ind])) + def test_ordered_coordinates(self): # Order coordinates, to ensure that the first dimension/the second dimension and so on.. # Always are in the same order to a given type (e.g. spatio_temporal= of coordinates