22. Exporting and Sharing Your Analysis
22.2 to_csv and to_excel with Blinkit Summaries
Why. CSV is universal. Excel (.xlsx) is what many Indian ops leads still open first. pandas can write both. Excel needs the openpyxl package once.
What.
DataFrame.to_csv(path, index=False)— text table.DataFrame.to_excel(path, index=False, sheet_name=...)— Excel sheet.ExcelWriter— several sheets in one workbook.
How.
Export a city summary
pip install openpyxlinside your venv (once).- Aggregate:
g = df.groupby(["city", "status"], as_index=False)["amount"].agg(orders="count", gmv="sum"). - Sort for humans: highest GMV first.
g.to_csv("outputs/city_status.csv", index=False).g.to_excel("outputs/city_status.xlsx", index=False, sheet_name="city_status").- Open the file outside Jupyter and check ₹ totals match
df["amount"].sum()for Delivered if that is your rule.
Worked example A — Build and export (fictional).
import pandas as pd
from pathlib import Path
Path("outputs").mkdir(exist_ok=True)
df = pd.DataFrame({
"order_id": [
"BLK-261022-001", "BLK-261022-002", "BLK-261022-003",
"AMN-261022-004", "BLK-261022-005", "BLK-261022-006",
"BLK-261022-007", "AMN-261022-008", "BLK-261022-009",
],
"city": [
"Pune", "Pune", "Solapur", "Nashik", "Kolhapur",
"Nagpur", "Sambhaji Nagar", "Pune", "Nashik",
],
"status": [
"Delivered", "Cancelled", "Delivered", "Delivered", "Delivered",
"Returned", "Delivered", "Delivered", "Delivered",
],
"amount": [189, 90, 120, 95, 210, 150, 340, 72, 88],
"customer": [
"Ruhi Bagale", "Amir", "Zoya", "Salman", "Ravina",
"Raja", "Rani", "Shraddha Bagale", "Shahrukh",
],
})
summary = (
df.groupby(["city", "status"], as_index=False)
.agg(orders=("order_id", "count"), gmv_inr=("amount", "sum"))
.sort_values(["gmv_inr", "city"], ascending=[False, True])
)
summary.to_csv("outputs/city_status.csv", index=False)
summary.to_excel("outputs/city_status.xlsx", index=False, sheet_name="city_status")
print(summary)
print("delivered gmv check", df.loc[df["status"].eq("Delivered"), "amount"].sum())
What you should see. A tidy sheet: one row per city×status, columns orders and gmv_inr. Pune Delivered should not include the Cancelled ₹90.
Worked example B — Multi-sheet workbook for Ravindra.
daily = (
df.assign(day="22-10-2026")
.groupby(["day", "city"], as_index=False)
.agg(orders=("order_id", "count"), gmv_inr=("amount", "sum"))
)
notes = pd.DataFrame({
"note": [
"Fictional sample for learning only.",
"GMV = sum of amount; confirm status filter with ops.",
"Contact for questions: analyst@example.com",
]
})
with pd.ExcelWriter("outputs/blinkit_friday_pack.xlsx", engine="openpyxl") as xlw:
summary.to_excel(xlw, sheet_name="city_status", index=False)
daily.to_excel(xlw, sheet_name="daily_city", index=False)
notes.to_excel(xlw, sheet_name="notes", index=False)
Worked example C — CSV for systems; Excel for people.
# UTF-8 CSV for pipelines / pandas peers
summary.to_csv("outputs/city_status_utf8.csv", index=False, encoding="utf-8")
# Excel-friendly CSV on some Windows setups (only if a peer asks)
summary.to_csv("outputs/city_status_utf8_sig.csv", index=False, encoding="utf-8-sig")
Prefer utf-8 by default. Use utf-8-sig when a colleague’s Excel mangles Marathi city notes (if you ever add them).
Practice task
Add a delivered_only sheet that filters status == "Delivered" before aggregating. Confirm sheet GMV equals the Delivered sum in Python.