<!-- skill: CSV Analysis | version: 1.0.0 | description: Analyze CSVs with Python/pandas — clean, summarize, chart, report | category: Python & Data -->

## Instructions
- Always inspect first: `df.head()`, `df.info()`, `df.describe()`, null counts — before any conclusion.
- Parse dates explicitly (`parse_dates=[...]`), strip whitespace from headers (`df.columns.str.strip()`).
- Handle missing data deliberately: drop, fill, or flag — never silently ignore; say which you did.
- One script per analysis (`analyze.py`), outputs to `report.md` + PNG charts (`matplotlib`, no interactive windows: `Agg` backend).
- Answer the actual question first (one number/table), then show working. Round numbers for humans.
- Never invent data: if a column is missing or empty, say so instead of guessing.

## Examples
- Sales CSV → monthly revenue table + bar chart + top-5 products.
- Sensor log → resample to hourly means, flag gaps > 1h, plot timeline.

## Workflows
1. Load + inspect (shape, dtypes, nulls, date range).
2. Clean (headers, types, duplicates, missing values — log each decision).
3. Answer the question (group/filter/aggregate).
4. Chart the key result, write `report.md` (question → answer → method → caveats).
5. Save the script so the analysis is re-runnable on fresh data.

## Templates
```python
# analyze.py — inspect → clean → answer → report
import pandas as pd
df = pd.read_csv("data.csv", parse_dates=["date"])
df.columns = df.columns.str.strip()
print(df.shape, df.dtypes)
print(df.isna().sum())  # decide: drop / fill / flag
monthly = df.groupby(pd.Grouper(key="date", freq="ME"))["amount"].sum()
print(monthly.tail(12))
monthly.plot(kind="bar", title="Monthly revenue").figure.savefig("monthly.png")
```

## Tools
- SARAH Run button executes `analyze.py` in the project folder; charts save beside it.
- `pip install pandas matplotlib` if missing.

## Advanced
- Joins: `merge(df1, df2, on=..., how=..., validate='m:1')` — the `validate` flag catches cardinality surprises early.
- Time done right: timezone-aware datetimes (`utc=True` then `tz_convert`), business-day resampling (`freq='B'`), rolling windows with `min_periods` set.
- Memory: `category` dtype for repeated strings, `usecols=` + `chunksize=` for files bigger than RAM, Parquet (`to_parquet`) as the working format — 10x smaller, typed.
- Pivot like a pro: `pivot_table(values, index, columns, aggfunc, margins=True)` for cross-tabs with totals.
- Charts that convince: seaborn style context, labeled axes + units, one message per chart, annotate the key number directly on it.
- Troubleshooting: mixed dtypes → `dtype=str` on load then convert deliberately; merge explosion → check duplicates first (`duplicated().sum()`); dates parsed as strings → `dayfirst`/format= explicit.

## Documentation
- pandas basics: https://pandas.pydata.org/docs/user_guide/10min.html
- matplotlib: https://matplotlib.org/stable/tutorials/pyplot.html
