use chrono::NaiveDate;
use pandrs::error::{Error, Result};
use pandrs::temporal::{date_range, Frequency, TimeSeries};
use pandrs::NA;
use std::str::FromStr;
#[allow(clippy::result_large_err)]
#[allow(clippy::result_large_err)]
fn main() -> Result<()> {
println!("=== Time Series Data Example ===");
let start_date = NaiveDate::from_str("2023-01-01").map_err(|e| Error::Format(e.to_string()))?;
let end_date = NaiveDate::from_str("2023-01-31").map_err(|e| Error::Format(e.to_string()))?;
let dates = date_range(start_date, end_date, Frequency::Daily, true)?;
println!("Date range length: {}", dates.len());
println!("First date: {}", dates[0]);
println!("Last date: {}", dates[dates.len() - 1]);
let mut values = Vec::with_capacity(dates.len());
for i in 0..dates.len() {
let day = i as f64;
let value = 100.0 + 10.0 * (day * 0.2).sin();
if i % 5 == 0 {
values.push(NA::NA);
} else {
values.push(NA::Value(value));
}
}
let time_series = TimeSeries::new(values, dates, Some("daily_values".to_string()))?;
println!("\n=== Time Series Basic Information ===");
println!("Length: {}", time_series.len());
let start_filter =
NaiveDate::from_str("2023-01-10").map_err(|e| Error::Format(e.to_string()))?;
let end_filter = NaiveDate::from_str("2023-01-20").map_err(|e| Error::Format(e.to_string()))?;
let filtered = time_series.filter_by_time(&start_filter, &end_filter)?;
println!("\n=== Time Filtering Results ===");
println!("Original time series length: {}", time_series.len());
println!("Filtered length: {}", filtered.len());
let window_size = 3;
let moving_avg = time_series.rolling_mean(window_size)?;
println!("\n=== Moving Average (Window Size: {window_size}) ===");
println!("Moving average length: {}", moving_avg.len());
println!("\n=== Comparison of Original Data and Moving Average (First 10 Rows) ===");
println!("Date\t\tOriginal\tMoving Average");
for i in 0..10.min(time_series.len()) {
let date = time_series.timestamps()[i];
let original = match time_series.values()[i] {
NA::Value(v) => format!("{v:.2}"),
NA::NA => "NA".to_string(),
};
let ma = match moving_avg.values()[i] {
NA::Value(v) => format!("{v:.2}"),
NA::NA => "NA".to_string(),
};
println!("{date}\t{original}\t\t{ma}");
}
let weekly = time_series.resample(Frequency::Weekly).mean()?;
println!("\n=== Weekly Resampling ===");
println!("Original time series length: {}", time_series.len());
println!("Resampled length: {}", weekly.len());
println!("\n=== Weekly Data ===");
println!("Date\t\tValue");
for i in 0..weekly.len() {
let date = weekly.timestamps()[i];
let value = match weekly.values()[i] {
NA::Value(v) => format!("{v:.2}"),
NA::NA => "NA".to_string(),
};
println!("{date}\t{value}");
}
println!("\n=== Time Series Sample Completed ===");
Ok(())
}