From e9e55565a2f33aeb1e0467f70856018e8ac5c9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niclas=20W=C3=BCstenbecker?= Date: Fri, 24 May 2024 14:41:38 +0200 Subject: [PATCH 1/3] add interpolation options to resample method --- src/traffic/core/flight.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/traffic/core/flight.py b/src/traffic/core/flight.py index 7513b08f..121fac1c 100644 --- a/src/traffic/core/flight.py +++ b/src/traffic/core/flight.py @@ -1658,6 +1658,7 @@ def resample( self, rule: str | int = "1s", how: None | str | dict[str, Iterable[str]] = "interpolate", + interpolation_options: dict[str, Any] = {}, projection: None | str | pyproj.Proj | "crs.Projection" = None, ) -> Flight: """Resample the trajectory at a given frequency or for a target number @@ -1680,6 +1681,18 @@ def resample( ``"interpolate"``, ``"ffill"``) and names of columns as values. Columns not included in any value are left as is. + :param interpolation_options: (default: ``{}``) + + - A dictionary with keyword arguments that will be passed to the + pandas :py:method:`pandas.Series.interpolate` method. + + Example usage: + To specify a fifth-degree polynomial interpolation, you can + pass the following dictionary: + + .. code-block:: python + interpolation_options = {"method": "polynomial", "order": 5} + :param projection: (default: ``None``) - By default, lat/lon are resampled with a linear interpolation; @@ -1729,7 +1742,10 @@ def resample( for meth, columns in how.items(): if meth is not None: idx = data.columns.get_indexer(columns) - value = getattr(data.iloc[:, idx], meth)() + kwargs = ( + interpolation_options if meth == "interpolate" else {} + ) + value = getattr(data.iloc[:, idx], meth)(**kwargs) data[data.columns[idx]] = value elif isinstance(rule, int): From 8bfc87508a2ed988eddd1866be6c784ba0743819 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niclas=20W=C3=BCstenbecker?= Date: Fri, 24 May 2024 15:15:25 +0200 Subject: [PATCH 2/3] add test for resample with interpolation_options --- tests/test_flight.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/test_flight.py b/tests/test_flight.py index 8b740089..abb8a10a 100644 --- a/tests/test_flight.py +++ b/tests/test_flight.py @@ -508,6 +508,36 @@ def test_resample_how_argument() -> None: check_dtype=False, ) + altitude_interpolate_quadratic = [ + 30000.0, + 28440.0, + 27160.0, + 26160.0, + 25440.0, + 25000.0, + 24840.0, + 24960.0, + 25360.0, + 26040.0, + 27000.0, + ] + resampled_interpolate_quadratic = Flight(df).resample( + "1s", + how="interpolate", + interpolation_options={"method": "polynomial", "order": 2}, + ) + pd.testing.assert_frame_equal( + resampled_interpolate_quadratic.data[["altitude", "fake"]], + pd.DataFrame( + { + "altitude": altitude_interpolate_quadratic, + "fake": fake_interpolate, + } + ), + check_dtype=False, + check_exact=False, # accomodate for small rounding errors + ) + resampled_ffill = Flight(df).resample("1s", how="ffill") pd.testing.assert_frame_equal( resampled_ffill.data[["altitude", "fake"]], From 820c029bc7639b7da7a82078c0d556e06633a625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niclas=20W=C3=BCstenbecker?= Date: Mon, 27 May 2024 10:07:21 +0200 Subject: [PATCH 3/3] rename interpolation_options to interpolate_kw --- src/traffic/core/flight.py | 10 ++++------ tests/test_flight.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/traffic/core/flight.py b/src/traffic/core/flight.py index 121fac1c..ea71a588 100644 --- a/src/traffic/core/flight.py +++ b/src/traffic/core/flight.py @@ -1658,7 +1658,7 @@ def resample( self, rule: str | int = "1s", how: None | str | dict[str, Iterable[str]] = "interpolate", - interpolation_options: dict[str, Any] = {}, + interpolate_kw: dict[str, Any] = {}, projection: None | str | pyproj.Proj | "crs.Projection" = None, ) -> Flight: """Resample the trajectory at a given frequency or for a target number @@ -1681,7 +1681,7 @@ def resample( ``"interpolate"``, ``"ffill"``) and names of columns as values. Columns not included in any value are left as is. - :param interpolation_options: (default: ``{}``) + :param interpolate_kw: (default: ``{}``) - A dictionary with keyword arguments that will be passed to the pandas :py:method:`pandas.Series.interpolate` method. @@ -1691,7 +1691,7 @@ def resample( pass the following dictionary: .. code-block:: python - interpolation_options = {"method": "polynomial", "order": 5} + interpolate_kw = {"method": "polynomial", "order": 5} :param projection: (default: ``None``) @@ -1742,9 +1742,7 @@ def resample( for meth, columns in how.items(): if meth is not None: idx = data.columns.get_indexer(columns) - kwargs = ( - interpolation_options if meth == "interpolate" else {} - ) + kwargs = interpolate_kw if meth == "interpolate" else {} value = getattr(data.iloc[:, idx], meth)(**kwargs) data[data.columns[idx]] = value diff --git a/tests/test_flight.py b/tests/test_flight.py index abb8a10a..fe0535d3 100644 --- a/tests/test_flight.py +++ b/tests/test_flight.py @@ -524,7 +524,7 @@ def test_resample_how_argument() -> None: resampled_interpolate_quadratic = Flight(df).resample( "1s", how="interpolate", - interpolation_options={"method": "polynomial", "order": 2}, + interpolate_kw={"method": "polynomial", "order": 2}, ) pd.testing.assert_frame_equal( resampled_interpolate_quadratic.data[["altitude", "fake"]],