Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ docs/text/_generated/

# Virtual environment
venv*
.venv/
activate

# IPython notebooks
Expand Down
24 changes: 24 additions & 0 deletions tests/units/utilities/test_dataframe_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,30 @@ def test_make_forecasting_frame_feature_extraction(self):
default_fc_parameters=MinimalFCParameters(),
)

def test_make_forecasting_frame_min_timeshift(self):
x = pd.Series([1, 2, 3, 4, 5])
# Default behavior
df_default, y_default = dataframe_functions.make_forecasting_frame(
x=x,
kind="test",
max_timeshift=3,
rolling_direction=1,
)
# With min_timeshift
df_filtered, y_filtered = dataframe_functions.make_forecasting_frame(
x=x,
kind="test",
max_timeshift=3,
rolling_direction=1,
min_timeshift=2,
)
# Check fewer rows (core behavior)
assert len(df_filtered) < len(df_default)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you know the data, it might be better to check the actual len

But using the default df & y, you can check whether the two equal on the intersection

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a more robust test in the latest commit, comparing the intersection between default and filtered outputs as suggested. Thanks for the review!

# Check target is aligned
assert len(y_filtered) == len(df_filtered.groupby("id").size())

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this the same as:

Suggested change
assert len(y_filtered) == len(df_filtered.groupby("id").size())
assert len(y_filtered) == df_filtered.nunique("id")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented your suggestion in the last commit.

# assert in filtered_df each "time" >= 2
assert all(df_filtered["time"] >= 2)


class GetIDsTestCase(TestCase):
def test_get_id__correct_DataFrame(self):
Expand Down
10 changes: 9 additions & 1 deletion tsfresh/utilities/dataframe_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ def roll_time_series(
return df_shift.sort_values(by=["id", column_sort or "sort"])


def make_forecasting_frame(x, kind, max_timeshift, rolling_direction):
def make_forecasting_frame(x, kind, max_timeshift, rolling_direction, min_timeshift=0):
"""
Takes a singular time series x and constructs a DataFrame df and target vector y that can be used for a time series
forecasting task.
Expand All @@ -603,6 +603,8 @@ def make_forecasting_frame(x, kind, max_timeshift, rolling_direction):
:type rolling_direction: int
:param max_timeshift: If not None, shift only up to max_timeshift. If None, shift as often as possible.
:type max_timeshift: int
:param min_timeshift: Minimum shift size to begin creating windows. Smaller windows are discarded. Default is 0.
:type min_timeshift: int

:return: time series container df, target vector y
:rtype: (pd.DataFrame, pd.Series)
Expand All @@ -623,6 +625,7 @@ def make_forecasting_frame(x, kind, max_timeshift, rolling_direction):
column_kind="kind",
rolling_direction=rolling_direction,
max_timeshift=max_timeshift,
min_timeshift=min_timeshift,
)

# drop the rows which should actually be predicted
Expand All @@ -646,6 +649,11 @@ def mask_first(x):
# df_shift index
y.index = map(lambda x: ("id", x), y.index)

# align y with df_shift ids
# align y with df_shift ids
Comment thread
nils-braun marked this conversation as resolved.
Resolved
valid_ids = set(df_shift["id"].unique())
y = y[y.index.isin(valid_ids)]

return df_shift, y


Expand Down
Loading