timelined_array 0.0.4__tar.gz → 0.0.6__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.
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.1
2
+ Name: timelined_array
3
+ Version: 0.0.6
4
+ Summary: Manage easily 1 or multidimensionnal samples numpy arrays that are time related. Extends numpy without removing any of it's abilities on such arrays.
5
+ Author-Email: Timothe Jost <timothe.jost@wanadoo.fr>
6
+ License: MIT
7
+ Requires-Python: >=3.11
8
+ Requires-Dist: numpy
9
+ Description-Content-Type: text/markdown
10
+
11
+ # timelined_array
12
+
13
+ ## Overview
14
+ The TimelinedArray package provides a set of classes and utilities for working with time-indexed arrays. It extends the functionality of NumPy arrays to include time-based indexing and operations, making it easier to work with time-series data.
15
+
16
+ ## Classes
17
+ ### Timeline
18
+ A subclass of np.ndarray that represents a timeline associated with the array. It includes methods for creating uniformly spaced timelines and calculating time steps.
19
+
20
+ ### Boundary
21
+ An enumeration that defines inclusive and exclusive boundaries for time indexing.
22
+
23
+ ### TimeIndexer
24
+ A class that provides methods for converting time values to array indices and for indexing arrays based on time.
25
+
26
+ ### TimeMixin
27
+ A mixin class that adds time-related methods and properties to arrays, including methods for aligning, transposing, and moving axes.
28
+
29
+ ### TimePacker
30
+ A class for packing arrays with their associated timelines. Usefull to plot data fast to matplotlib.
31
+
32
+ ### TimelinedArray
33
+ A subclass of np.ndarray that includes a timeline and a time dimension. It provides methods for time-based indexing and operations.
34
+
35
+ ### MaskedTimelinedArray
36
+ A subclass of np.ma.MaskedArray that includes a timeline and a time dimension. It provides methods for time-based indexing and operations on masked arrays.
37
+
38
+ ### Seconds
39
+ A simple class for converting seconds to array indices based on a given sampling frequency.
40
+
41
+ ## Installation
42
+ To install the TimelinedArray package, simply type in your environment activated console :
43
+ ```bash
44
+ pip install timelined_array
45
+ ```
46
+
47
+ The package can be found on PyPI at : https://pypi.org/project/timelined_array/
48
+
49
+ ## Usage
50
+
51
+ ### Imports
52
+ ```python
53
+ from timelined_array import TimelinedArray, MaskedTimelinedArray, Boundary, Timeline
54
+ ```
55
+
56
+ ### Creating a TimelinedArray
57
+ ```python
58
+ import numpy as np
59
+ from timelined_array import TimelinedArray
60
+
61
+ data = np.random.rand(100, 10)
62
+ timeline = np.linspace(0, 10, 100)
63
+ timelined_array = TimelinedArray(data, timeline=timeline, time_dimension=0)
64
+ ```
65
+ ### Time-based Indexing
66
+ ```python
67
+ # Access data at a specific time
68
+ data_at_time = timelined_array.itime[5.0]
69
+
70
+ # Aligning arrays
71
+ aligned_array = TimelinedArray.align_from_iterable([timelined_array, another_timelined_array])
72
+ ```
73
+
74
+
75
+ ### Masked TimelinedArray
76
+ ```python
77
+ from timelined_array import MaskedTimelinedArray
78
+
79
+ masked_data = np.ma.masked_array(data, mask=data > 0.5)
80
+ masked_timelined_array = MaskedTimelinedArray(masked_data, timeline=timeline, time_dimension=0)
81
+ ```
82
+
83
+ ### Converting Seconds to Index
84
+ ```python
85
+ masked_data.itime.time_to_index(5.0)
86
+ ```
87
+
88
+ ## Misc
89
+
90
+ ### License
91
+ This package is licensed under the MIT License. See the LICENSE file for more details.
92
+
93
+ ### Contributing
94
+ Contributions are welcome! Please submit a pull request or open an issue to discuss any changes.
95
+
96
+ ### Contact
97
+ For any questions or issues, please contact the package maintainer.
@@ -0,0 +1,87 @@
1
+ # timelined_array
2
+
3
+ ## Overview
4
+ The TimelinedArray package provides a set of classes and utilities for working with time-indexed arrays. It extends the functionality of NumPy arrays to include time-based indexing and operations, making it easier to work with time-series data.
5
+
6
+ ## Classes
7
+ ### Timeline
8
+ A subclass of np.ndarray that represents a timeline associated with the array. It includes methods for creating uniformly spaced timelines and calculating time steps.
9
+
10
+ ### Boundary
11
+ An enumeration that defines inclusive and exclusive boundaries for time indexing.
12
+
13
+ ### TimeIndexer
14
+ A class that provides methods for converting time values to array indices and for indexing arrays based on time.
15
+
16
+ ### TimeMixin
17
+ A mixin class that adds time-related methods and properties to arrays, including methods for aligning, transposing, and moving axes.
18
+
19
+ ### TimePacker
20
+ A class for packing arrays with their associated timelines. Usefull to plot data fast to matplotlib.
21
+
22
+ ### TimelinedArray
23
+ A subclass of np.ndarray that includes a timeline and a time dimension. It provides methods for time-based indexing and operations.
24
+
25
+ ### MaskedTimelinedArray
26
+ A subclass of np.ma.MaskedArray that includes a timeline and a time dimension. It provides methods for time-based indexing and operations on masked arrays.
27
+
28
+ ### Seconds
29
+ A simple class for converting seconds to array indices based on a given sampling frequency.
30
+
31
+ ## Installation
32
+ To install the TimelinedArray package, simply type in your environment activated console :
33
+ ```bash
34
+ pip install timelined_array
35
+ ```
36
+
37
+ The package can be found on PyPI at : https://pypi.org/project/timelined_array/
38
+
39
+ ## Usage
40
+
41
+ ### Imports
42
+ ```python
43
+ from timelined_array import TimelinedArray, MaskedTimelinedArray, Boundary, Timeline
44
+ ```
45
+
46
+ ### Creating a TimelinedArray
47
+ ```python
48
+ import numpy as np
49
+ from timelined_array import TimelinedArray
50
+
51
+ data = np.random.rand(100, 10)
52
+ timeline = np.linspace(0, 10, 100)
53
+ timelined_array = TimelinedArray(data, timeline=timeline, time_dimension=0)
54
+ ```
55
+ ### Time-based Indexing
56
+ ```python
57
+ # Access data at a specific time
58
+ data_at_time = timelined_array.itime[5.0]
59
+
60
+ # Aligning arrays
61
+ aligned_array = TimelinedArray.align_from_iterable([timelined_array, another_timelined_array])
62
+ ```
63
+
64
+
65
+ ### Masked TimelinedArray
66
+ ```python
67
+ from timelined_array import MaskedTimelinedArray
68
+
69
+ masked_data = np.ma.masked_array(data, mask=data > 0.5)
70
+ masked_timelined_array = MaskedTimelinedArray(masked_data, timeline=timeline, time_dimension=0)
71
+ ```
72
+
73
+ ### Converting Seconds to Index
74
+ ```python
75
+ masked_data.itime.time_to_index(5.0)
76
+ ```
77
+
78
+ ## Misc
79
+
80
+ ### License
81
+ This package is licensed under the MIT License. See the LICENSE file for more details.
82
+
83
+ ### Contributing
84
+ Contributions are welcome! Please submit a pull request or open an issue to discuss any changes.
85
+
86
+ ### Contact
87
+ For any questions or issues, please contact the package maintainer.
@@ -10,7 +10,7 @@ dependencies = [
10
10
  requires-python = ">=3.11"
11
11
  readme = "README.md"
12
12
  dynamic = []
13
- version = "0.0.4"
13
+ version = "0.0.6"
14
14
 
15
15
  [project.license]
16
16
  text = "MIT"
@@ -1,3 +1,3 @@
1
- __version__ = "0.0.4"
1
+ __version__ = "0.0.6"
2
2
 
3
3
  from .time import TimelinedArray, MaskedTimelinedArray, Seconds, Boundary
@@ -21,7 +21,7 @@ class TimeCompatibleProtocol(Protocol):
21
21
  def __array__(self) -> np.ndarray: ...
22
22
 
23
23
  @property
24
- def shape(self) -> Tuple[int]: ...
24
+ def shape(self) -> Tuple[int, ...]: ...
25
25
 
26
26
  @property
27
27
  def ndim(self) -> int: ...
@@ -347,11 +347,11 @@ class TimeMixin:
347
347
  time_dimension: int
348
348
  timeline: Timeline
349
349
 
350
- def _time_dimension_in_axis(self, axis: int | Tuple[int] | None) -> bool:
350
+ def _time_dimension_in_axis(self, axis: int | Tuple[int, ...] | None) -> bool:
351
351
  """Check if the time dimension is present in the specified axis.
352
352
 
353
353
  Args:
354
- axis (int | Tuple[int] | None): The axis to check for the time dimension.
354
+ axis (int | Tuple[int, ...] | None): The axis to check for the time dimension.
355
355
 
356
356
  Returns:
357
357
  bool: True if the time dimension is present in the axis, False otherwise.
@@ -502,11 +502,11 @@ class TimeMixin:
502
502
 
503
503
  return index, final_timeline, final_time_dimension
504
504
 
505
- def _get_indexed_times(self, index: int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray):
505
+ def _get_indexed_times(self, index: int | Tuple[int, ...] | slice | Tuple[slice] | List | np.ndarray):
506
506
  """Get indexed times based on the provided index.
507
507
 
508
508
  Args:
509
- index (int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray): The index to retrieve times from.
509
+ index (int | Tuple[int, ...] | slice | Tuple[slice] | List | np.ndarray): The index to retrieve times from.
510
510
 
511
511
  Returns:
512
512
  np.ndarray: The indexed times based on the provided index.
@@ -531,12 +531,12 @@ class TimeMixin:
531
531
 
532
532
  return obj.shape == ()
533
533
 
534
- def _finish_axis_removing_operation(self, result: TimeCompatibleProtocol, axis: int | Tuple[int] | None):
534
+ def _finish_axis_removing_operation(self, result: TimeCompatibleProtocol, axis: int | Tuple[int, ...] | None):
535
535
  """Finish axis removing operation.
536
536
 
537
537
  Args:
538
538
  result (TimeCompatibleProtocol): The result of the operation.
539
- axis (int | Tuple[int] | None): The axis or axes to remove.
539
+ axis (int | Tuple[int, ...] | None): The axis or axes to remove.
540
540
 
541
541
  Returns:
542
542
  TimeCompatibleProtocol: The result after finishing the axis removing operation.
@@ -544,7 +544,7 @@ class TimeMixin:
544
544
 
545
545
  if not isinstance(result, np.ndarray):
546
546
  return result
547
- if not self._is_single_element(result):
547
+ if self._is_single_element(result):
548
548
  return result.item()
549
549
  if self._time_dimension_in_axis(axis):
550
550
  return np.asarray(result)
@@ -641,6 +641,40 @@ class TimeMixin:
641
641
 
642
642
  return self.itime[start:][:element_nb] # type: ignore
643
643
 
644
+ def shift_values(
645
+ self,
646
+ period: int | Tuple[int, ...] | slice | Tuple[slice, ...] | List | np.ndarray = 0,
647
+ axis=None,
648
+ time_period=True,
649
+ ):
650
+ """Shifts the values of the array along the specified axis by the given period.
651
+
652
+ Args:
653
+ period (int): The period by which to shift the values.
654
+ axis (int, optional): The axis along which to shift the values. Defaults to None.
655
+ time_period (bool, optional): If True, the shift is applied based on time. Defaults to True.
656
+
657
+ Returns:
658
+ numpy.ndarray: The array with shifted values.
659
+ """
660
+
661
+ if axis is None:
662
+ axis = self.time_dimension
663
+
664
+ indexer = []
665
+ for dim in range(len(self.shape)):
666
+ if dim == axis:
667
+ # make a new axis to account fo the axis loss of the .mean later
668
+ indexer.append(np.newaxis)
669
+ else:
670
+ # select all with slice(None) equivalent to ":"
671
+ indexer.append(slice(None))
672
+ indexer = tuple(indexer)
673
+
674
+ shift_area = self.itime.__getitem__(period) if time_period else self.__getitem__(period)
675
+
676
+ return self - np.repeat(shift_area.mean(axis=axis).__getitem__(tuple(indexer)), self.shape[axis], axis=axis)
677
+
644
678
  def swapaxes(self: TimeCompatibleProtocol, axis1: int, axis2: int):
645
679
  """Swap the two specified axes of the TimelinedArray.
646
680
 
@@ -701,12 +735,12 @@ class TimeMixin:
701
735
 
702
736
  return self.transpose()
703
737
 
704
- def moveaxis(self: TimeCompatibleProtocol, source: int | Tuple[int], destination: int | Tuple[int]):
738
+ def moveaxis(self: TimeCompatibleProtocol, source: int | Tuple[int, ...], destination: int | Tuple[int, ...]):
705
739
  """Move the axis of the array to new positions.
706
740
 
707
741
  Args:
708
- source (int or Tuple[int]): The source position(s) of the axis to move.
709
- destination (int or Tuple[int]): The destination position(s) to move the axis to.
742
+ source (int or Tuple[int, ...]): The source position(s) of the axis to move.
743
+ destination (int or Tuple[int, ...]): The destination position(s) to move the axis to.
710
744
 
711
745
  Returns:
712
746
  TimeCompatibleProtocol: A new array with the axis moved to the specified destination.
@@ -777,11 +811,14 @@ class TimeMixin:
777
811
  # TimelinedArray.time_dimension and TimelinedArray.timeline are set. good to go
778
812
  return rolled_array
779
813
 
780
- def mean(self: TimeCompatibleProtocol, axis: int | Tuple[int] | None = None, dtype=None, out=None, keepdims=False):
814
+ def mean(
815
+ self: TimeCompatibleProtocol, axis: int | Tuple[int, ...] | None = None, dtype=None, out=None, keepdims=False
816
+ ):
781
817
  """Calculates the mean along the specified axis.
782
818
 
783
819
  Args:
784
- axis (int | Tuple[int] | None): Axis or axes along which to perform the mean operation. Default is None.
820
+ axis (int | Tuple[int, ...] | None): Axis or axes along which to perform the mean operation.
821
+ Default is None.
785
822
  dtype: Data-type to use in the computation.
786
823
  out: Output array where the result is stored.
787
824
  keepdims (bool): If True, the reduced dimensions are retained in the output array.
@@ -794,11 +831,13 @@ class TimeMixin:
794
831
  return self._finish_axis_removing_operation(result, axis)
795
832
 
796
833
  # Override other reduction methods similarly if needed
797
- def sum(self: TimeCompatibleProtocol, axis: int | Tuple[int] | None = None, dtype=None, out=None, keepdims=False):
834
+ def sum(
835
+ self: TimeCompatibleProtocol, axis: int | Tuple[int, ...] | None = None, dtype=None, out=None, keepdims=False
836
+ ):
798
837
  """Calculate the sum along the specified axis.
799
838
 
800
839
  Args:
801
- axis (int | Tuple[int] | None): Axis or axes along which a sum is performed.
840
+ axis (int | Tuple[int, ...] | None): Axis or axes along which a sum is performed.
802
841
  The default is to sum over all the dimensions of the input array.
803
842
  dtype: The type of the returned array and of the accumulator in which the elements are summed.
804
843
  If dtype is not specified, it defaults to the dtype of a, unless a has an integer dtype
@@ -818,12 +857,17 @@ class TimeMixin:
818
857
  return self._finish_axis_removing_operation(result, axis)
819
858
 
820
859
  def std(
821
- self: TimeCompatibleProtocol, axis: int | Tuple[int] | None = None, dtype=None, out=None, ddof=0, keepdims=False
860
+ self: TimeCompatibleProtocol,
861
+ axis: int | Tuple[int, ...] | None = None,
862
+ dtype=None,
863
+ out=None,
864
+ ddof=0,
865
+ keepdims=False,
822
866
  ):
823
867
  """Calculate the standard deviation along the specified axis.
824
868
 
825
869
  Args:
826
- axis (int or Tuple[int] or None): Axis or axes along which the standard deviation is computed.
870
+ axis (int or Tuple[int, ...] or None): Axis or axes along which the standard deviation is computed.
827
871
  The default is to compute the standard deviation of the flattened array.
828
872
  dtype: Data-type of the result. If not provided, the data-type of the input is used.
829
873
  out: Output array with the same shape as input array, placed with the result.
@@ -841,13 +885,18 @@ class TimeMixin:
841
885
  return self._finish_axis_removing_operation(result, axis)
842
886
 
843
887
  def var(
844
- self: TimeCompatibleProtocol, axis: int | Tuple[int] | None = None, dtype=None, out=None, ddof=0, keepdims=False
888
+ self: TimeCompatibleProtocol,
889
+ axis: int | Tuple[int, ...] | None = None,
890
+ dtype=None,
891
+ out=None,
892
+ ddof=0,
893
+ keepdims=False,
845
894
  ):
846
895
  """Calculate the variance along the specified axis.
847
896
 
848
897
  Args:
849
898
  self (TimeCompatibleProtocol): The input data.
850
- axis (int | Tuple[int] | None): Axis or axes along which the variance is computed.
899
+ axis (int | Tuple[int, ...] | None): Axis or axes along which the variance is computed.
851
900
  The default is to compute the variance of the flattened array.
852
901
  dtype: Data-type of the result. If not provided, the data-type of the input is used.
853
902
  out: Alternative output array in which to place the result.
@@ -1114,12 +1163,12 @@ class TimelinedArray(TimeMixin, np.ndarray, TimeCompatibleProtocol):
1114
1163
  return super().__array_function__(func, types, args, kwargs)
1115
1164
 
1116
1165
  def __getitem__(
1117
- self, index: int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray
1166
+ self, index: int | Tuple[int, ...] | slice | Tuple[slice, ...] | List | np.ndarray
1118
1167
  ) -> "TimelinedArray | np.ndarray":
1119
1168
  """Get item from TimelinedArray based on index or slice.
1120
1169
 
1121
1170
  Args:
1122
- index (int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray): Index or slice to retrieve item.
1171
+ index (int | Tuple[int, ...] | slice | Tuple[slice] | List | np.ndarray): Index or slice to retrieve item.
1123
1172
 
1124
1173
  Returns:
1125
1174
  TimelinedArray | np.ndarray: Indexed result based on the provided index.
@@ -1145,13 +1194,14 @@ class TimelinedArray(TimeMixin, np.ndarray, TimeCompatibleProtocol):
1145
1194
  def __repr__(self):
1146
1195
  """Return a string representation of the object with the class name and the array representation."""
1147
1196
 
1148
- return type(self).__name__ + np.array(self).__repr__()[5:]
1197
+ # [5:] serves to remove the 'array' part for the original array repr string
1198
+ return type(self).__name__ + np.asarray(self).__repr__()[5:]
1149
1199
 
1150
1200
  def __str__(self):
1151
1201
  """Return a string representation of the object by concatenating the class name with the string
1152
1202
  representation of the object as a NumPy array."""
1153
1203
 
1154
- return type(self).__name__ + np.array(self).__str__()
1204
+ return type(self).__name__ + np.asarray(self).__str__()
1155
1205
 
1156
1206
  @staticmethod
1157
1207
  def align_from_iterable(iterable) -> "TimelinedArray":
@@ -1249,12 +1299,12 @@ class MaskedTimelinedArray(TimeMixin, np.ma.MaskedArray, TimeCompatibleProtocol)
1249
1299
  self.time_dimension = getattr(obj, "time_dimension", 0)
1250
1300
 
1251
1301
  def __getitem__(
1252
- self, index: int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray
1302
+ self, index: int | Tuple[int, ...] | slice | Tuple[slice] | List | np.ndarray
1253
1303
  ) -> "MaskedTimelinedArray | np.ma.MaskedArray":
1254
1304
  """Get item from the MaskedTimelinedArray based on the provided index.
1255
1305
 
1256
1306
  Args:
1257
- index (int | Tuple[int] | slice | Tuple[slice] | List | np.ndarray): The index or slice to retrieve.
1307
+ index (int | Tuple[int, ...] | slice | Tuple[slice] | List | np.ndarray): The index or slice to retrieve.
1258
1308
 
1259
1309
  Returns:
1260
1310
  MaskedTimelinedArray | np.ma.MaskedArray: The masked array or MaskedTimelinedArray based on the index.
@@ -1,11 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: timelined_array
3
- Version: 0.0.4
4
- Summary: Manage easily 1 or multidimensionnal samples numpy arrays that are time related. Extends numpy without removing any of it's abilities on such arrays.
5
- Author-Email: Timothe Jost <timothe.jost@wanadoo.fr>
6
- License: MIT
7
- Requires-Python: >=3.11
8
- Requires-Dist: numpy
9
- Description-Content-Type: text/markdown
10
-
11
- # timelined_array
@@ -1 +0,0 @@
1
- # timelined_array
File without changes