agrisense-backend / MandiPricePredictionSystem /scripts /analytics_build_summary.py
Karthik Reddy
added crop recommendation system and restructured files
e2cc26b
Raw
History Blame Contribute Delete
2.78 kB
# scripts/analytics_build_summary.py
from pathlib import Path
import numpy as np
import pandas as pd
FORECAST_PATH = Path("outputs/mandi_commodity_all_forecasts_moirai.csv")
OUT_SUMMARY_PATH = Path("outputs/analytics_mandi_commodity_summary.csv")
def compute_group_stats(group: pd.DataFrame) -> pd.Series:
"""
Compute summary stats for one (Mandi, Commodity) group
over the Moirai forecast horizon.
"""
prices = group["pred_modal_price"].values.astype(float)
mean_price = float(np.mean(prices))
min_price = float(np.min(prices))
max_price = float(np.max(prices))
std_price = float(np.std(prices))
# volatility as % of mean (avoid divide by zero)
vol_pct = float(std_price / mean_price) if mean_price != 0 else np.nan
# simple linear trend: price ~ a * t + b
t = np.arange(len(prices))
if len(prices) >= 2:
slope, intercept = np.polyfit(t, prices, 1)
else:
slope, intercept = np.nan, np.nan
# day-to-day percentage changes
if len(prices) >= 2:
pct_changes = np.diff(prices) / prices[:-1]
max_up = float(np.max(pct_changes))
max_down = float(np.min(pct_changes))
max_abs_move = float(np.max(np.abs(pct_changes)))
else:
max_up = max_down = max_abs_move = np.nan
# spike / crash flags (thresholds can be tuned)
spike_flag = bool(max_up > 0.10) # > +10% jump in one day
crash_flag = bool(max_down < -0.10) # < -10% drop in one day
return pd.Series(
{
"forecast_mean_price": mean_price,
"forecast_min_price": min_price,
"forecast_max_price": max_price,
"forecast_std_price": std_price,
"forecast_volatility_pct": vol_pct,
"trend_slope_per_day": float(slope),
"max_daily_pct_up": max_up,
"max_daily_pct_down": max_down,
"max_abs_daily_pct_move": max_abs_move,
"has_spike": spike_flag,
"has_crash": crash_flag,
}
)
def main():
print(f"Loading Moirai forecasts from {FORECAST_PATH} ...")
df = pd.read_csv(FORECAST_PATH)
# ensure date is datetime for potential future use
df["date"] = pd.to_datetime(df["date"])
group_cols = [c for c in ["Mandi", "Commodity", "State", "district_name"] if c in df.columns]
print(f"Grouping by: {group_cols}")
grouped = df.groupby(group_cols, dropna=False)
summary_rows = grouped.apply(compute_group_stats).reset_index()
OUT_SUMMARY_PATH.parent.mkdir(parents=True, exist_ok=True)
summary_rows.to_csv(OUT_SUMMARY_PATH, index=False)
print(f"Saved mandi+commodity summary analytics to: {OUT_SUMMARY_PATH}")
print(f"Summary shape: {summary_rows.shape}")
if __name__ == "__main__":
main()