Skip to content

Commit a1c024d

Browse files
committed
update dataset build
1 parent 55e80bf commit a1c024d

3 files changed

Lines changed: 546 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,4 @@ coverage.xml
9494
*.log
9595
/weights/
9696
!/weights/.gitkeep
97+
CLAUDE.md

tests/test_data/test_timeseries.py

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,270 @@ def test_different_modes(self):
283283
mode=mode,
284284
)
285285
self.assertEqual(seq.mode, mode)
286+
287+
def test_from_df_basic(self):
288+
"""Test from_df with basic parameters."""
289+
df = pd.DataFrame(
290+
{
291+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
292+
"value": np.random.randn(100).cumsum(),
293+
}
294+
)
295+
296+
seq = TimeSeriesSequence.from_df(
297+
df,
298+
time_col="date",
299+
target_col="value",
300+
train_length=10,
301+
predict_length=5,
302+
)
303+
304+
self.assertEqual(seq.train_sequence_length, 10)
305+
self.assertEqual(seq.predict_sequence_length, 5)
306+
self.assertGreater(len(seq.sequences), 0)
307+
308+
def test_from_df_with_index(self):
309+
"""Test from_df using DataFrame index as time column."""
310+
df = pd.DataFrame(
311+
{
312+
"value": np.random.randn(100).cumsum(),
313+
},
314+
index=pd.date_range("2023-01-01", periods=100, freq="D"),
315+
)
316+
317+
seq = TimeSeriesSequence.from_df(
318+
df,
319+
target_col="value",
320+
train_length=10,
321+
predict_length=5,
322+
)
323+
324+
self.assertEqual(seq.train_sequence_length, 10)
325+
self.assertEqual(seq.predict_sequence_length, 5)
326+
self.assertGreater(len(seq.sequences), 0)
327+
328+
def test_from_df_with_groups(self):
329+
"""Test from_df with grouped time series."""
330+
df = pd.DataFrame(
331+
{
332+
"date": pd.date_range("2023-01-01", periods=200, freq="D").tolist() * 2,
333+
"group": ["A"] * 200 + ["B"] * 200,
334+
"value": np.random.randn(400).cumsum(),
335+
}
336+
)
337+
338+
seq = TimeSeriesSequence.from_df(
339+
df,
340+
time_col="date",
341+
target_col="value",
342+
group_col="group",
343+
train_length=10,
344+
predict_length=5,
345+
)
346+
347+
self.assertEqual(seq.group_ids, ["group"])
348+
self.assertGreater(len(seq.sequences), 0)
349+
350+
def test_from_df_multiple_targets(self):
351+
"""Test from_df with multiple target columns."""
352+
df = pd.DataFrame(
353+
{
354+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
355+
"value1": np.random.randn(100).cumsum(),
356+
"value2": np.random.randn(100).cumsum(),
357+
}
358+
)
359+
360+
seq = TimeSeriesSequence.from_df(
361+
df,
362+
time_col="date",
363+
target_col=["value1", "value2"],
364+
train_length=10,
365+
predict_length=5,
366+
)
367+
368+
self.assertEqual(len(seq.target), 2)
369+
self.assertIn("value1", seq.target)
370+
self.assertIn("value2", seq.target)
371+
372+
def test_from_df_fill_missing_dates(self):
373+
"""Test from_df with missing date filling."""
374+
# Create data with missing dates
375+
dates = pd.date_range("2023-01-01", periods=100, freq="D")
376+
# Remove some dates
377+
dates_with_gaps = dates.delete([10, 20, 30, 40])
378+
379+
df = pd.DataFrame(
380+
{
381+
"date": dates_with_gaps,
382+
"value": np.random.randn(len(dates_with_gaps)).cumsum(),
383+
}
384+
)
385+
386+
seq = TimeSeriesSequence.from_df(
387+
df,
388+
time_col="date",
389+
target_col="value",
390+
train_length=10,
391+
predict_length=5,
392+
fill_missing_dates=True,
393+
freq="D",
394+
)
395+
396+
# Should have filled the missing dates
397+
self.assertEqual(len(seq.data), 100)
398+
399+
def test_from_df_fillna(self):
400+
"""Test from_df with NaN filling."""
401+
df = pd.DataFrame(
402+
{
403+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
404+
"value": np.random.randn(100).cumsum(),
405+
}
406+
)
407+
# Add some NaN values
408+
df.loc[10:15, "value"] = np.nan
409+
410+
seq = TimeSeriesSequence.from_df(
411+
df,
412+
time_col="date",
413+
target_col="value",
414+
train_length=10,
415+
predict_length=5,
416+
fillna_value=0.0,
417+
)
418+
419+
# Check that NaN values were filled
420+
self.assertFalse(seq.data["value"].isna().any())
421+
422+
def test_from_df_with_feature_config(self):
423+
"""Test from_df with feature configuration."""
424+
df = pd.DataFrame(
425+
{
426+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
427+
"value": np.random.randn(100).cumsum(),
428+
}
429+
)
430+
431+
feature_config = {
432+
"date_features": {
433+
"type": "datetime",
434+
"features": ["dayofweek", "month"],
435+
"time_col": "date",
436+
}
437+
}
438+
439+
seq = TimeSeriesSequence.from_df(
440+
df,
441+
time_col="date",
442+
target_col="value",
443+
train_length=10,
444+
predict_length=5,
445+
feature_config=feature_config,
446+
)
447+
448+
# Check if datetime features were added
449+
self.assertTrue(any(col.startswith("date_") for col in seq.data.columns))
450+
451+
def test_from_df_validation_errors(self):
452+
"""Test from_df validation errors."""
453+
df = pd.DataFrame(
454+
{
455+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
456+
"value": np.random.randn(100).cumsum(),
457+
}
458+
)
459+
460+
# Test missing target_col
461+
with self.assertRaises(ValueError):
462+
TimeSeriesSequence.from_df(
463+
df,
464+
time_col="date",
465+
train_length=10,
466+
)
467+
468+
# Test missing train_length
469+
with self.assertRaises(ValueError):
470+
TimeSeriesSequence.from_df(
471+
df,
472+
time_col="date",
473+
target_col="value",
474+
)
475+
476+
# Test invalid time_col
477+
with self.assertRaises(KeyError):
478+
TimeSeriesSequence.from_df(
479+
df,
480+
time_col="invalid_col",
481+
target_col="value",
482+
train_length=10,
483+
)
484+
485+
# Test invalid target_col
486+
with self.assertRaises(KeyError):
487+
TimeSeriesSequence.from_df(
488+
df,
489+
time_col="date",
490+
target_col="invalid_col",
491+
train_length=10,
492+
)
493+
494+
# Test insufficient data length
495+
with self.assertRaises(ValueError):
496+
TimeSeriesSequence.from_df(
497+
df,
498+
time_col="date",
499+
target_col="value",
500+
train_length=90,
501+
predict_length=20,
502+
)
503+
504+
def test_from_df_numeric_time_index(self):
505+
"""Test from_df with numeric time index."""
506+
df = pd.DataFrame(
507+
{
508+
"time": range(100),
509+
"value": np.random.randn(100).cumsum(),
510+
}
511+
)
512+
513+
seq = TimeSeriesSequence.from_df(
514+
df,
515+
time_col="time",
516+
target_col="value",
517+
train_length=10,
518+
predict_length=5,
519+
)
520+
521+
self.assertEqual(seq.train_sequence_length, 10)
522+
self.assertGreater(len(seq.sequences), 0)
523+
524+
def test_from_df_with_stride(self):
525+
"""Test from_df with custom stride."""
526+
df = pd.DataFrame(
527+
{
528+
"date": pd.date_range("2023-01-01", periods=100, freq="D"),
529+
"value": np.random.randn(100).cumsum(),
530+
}
531+
)
532+
533+
seq = TimeSeriesSequence.from_df(
534+
df,
535+
time_col="date",
536+
target_col="value",
537+
train_length=10,
538+
predict_length=5,
539+
stride=2,
540+
)
541+
542+
self.assertEqual(seq.stride, 2)
543+
# With stride=2, we should have fewer sequences
544+
seq_stride1 = TimeSeriesSequence.from_df(
545+
df,
546+
time_col="date",
547+
target_col="value",
548+
train_length=10,
549+
predict_length=5,
550+
stride=1,
551+
)
552+
self.assertLess(len(seq.sequences), len(seq_stride1.sequences))

0 commit comments

Comments
 (0)