Free tutorials & notes in Hindi & English · Clean code examples 🧰 मुफ़्त PDF और फ़ोटो टूल्स →
🧹 Week 3 – Data Cleaning और EDA  ·  दिन 19

दिन 19: Mini Project: Retail Sales EDA

⏱ 3–4 hours📶 Project🎯 100% self-study
दिन 19 / 60

✅ आज आप सीखेंगे

  • अस्पष्ट brief को 6 business सवालों में बदलना
  • Reusable function से data साफ़ और समृद्ध करना
  • KPIs: revenue, AOV, orders, rating
  • हर सवाल का जवाब table + chart से
  • एक पेज की management summary लिखना

🏢 असली दुनिया में

BazaarKart के CEO लिखते हैं: “हम 2025 की planning कर रहे हैं। बताइए 2024 में क्या हुआ और हमें कहाँ invest करना चाहिए।” बस इतना ही। यह project दिखाता है कि data analyst ऐसे message को numbers, charts और सुझावों में कैसे बदलता है – ऐसा project जो interviews जिताता है।

Step 1: brief को सवालों में बदलें

#Business सवालAnalysis
Q12024 कितना बड़ा रहा?KPIs
Q2साल भर sales कैसे बदली?Monthly trend
Q3कौन से शहर और categories revenue लाते हैं?groupby + pivot
Q4Discounts फ़ायदा देते हैं या नुकसान?Discount bands vs revenue और rating
Q5हमारे customers कौन हैं?Age groups, gender, payment
Q6Customers कहाँ नाराज़ हैं?Rating analysis

Step 2: load, clean, enrich

Python
import pandas as pd

def load_sales(path="sales_data.csv"):
    df = pd.read_csv(path, parse_dates=["order_date"]).drop_duplicates()
    df["customer_age"] = df["customer_age"].fillna(df["customer_age"].median())
    df["revenue"] = df["quantity"] * df["unit_price"] * (1 - df["discount"])
    df["month"] = df["order_date"].dt.to_period("M")
    df["age_group"] = pd.cut(df["customer_age"], [17, 24, 34, 44, 60], labels=["18-24", "25-34", "35-44", "45+"])
    df["disc_band"] = pd.cut(df["discount"], [-0.01, 0, 0.1, 0.2, 0.3], labels=["None", "1-10%", "11-20%", "21-30%"])
    return df

df = load_sales()
df.to_pickle("sales_ready.pkl")                 # reuse in the next cells
print(df.shape, "| rating missing:", df["rating"].isna().sum())
print(df[["order_date", "city", "product", "revenue", "age_group", "disc_band"]].head(3))
(2000, 17) | rating missing: 35 order_date city product revenue age_group disc_band 0 2024-01-01 Delhi Jeans 2440.0 45+ None 1 2024-01-01 Mumbai Sneakers 2094.3 35-44 1-10% 2 2024-01-01 Mumbai Tea 1kg 2625.0 18-24 None

Q1: KPIs

Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
kpi = {"Revenue (₹ lakh)": round(df["revenue"].sum() / 1e5, 2),
       "Orders": len(df),
       "Units sold": int(df["quantity"].sum()),
       "Avg order value (₹)": round(df["revenue"].mean()),
       "Avg rating": round(df["rating"].mean(), 2),
       "Prepaid share %": round((df["payment_mode"] != "Cash on Delivery").mean() * 100, 1)}
for k, v in kpi.items():
    print(f"{k:22s} {v}")
Revenue (₹ lakh) 68.8 Orders 2000 Units sold 3890 Avg order value (₹) 3440 Avg rating 4.06 Prepaid share % 80.4

Q2: monthly trend

Python
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_pickle("sales_ready.pkl")
m = df.groupby("month").agg(revenue=("revenue", "sum"), orders=("order_id", "count"))
m["revenue_lakh"] = (m["revenue"] / 1e5).round(2)
print(m[["orders", "revenue_lakh"]].to_string())
fig, ax = plt.subplots(figsize=(10, 4))
ax.bar(m.index.strftime("%b"), m["revenue_lakh"], color=["#dc2626" if x in (10, 11) else "#818cf8" for x in m.index.month])
ax.set_title("Monthly revenue 2024 – the festive season (Oct–Nov) is the business"); ax.set_ylabel("₹ lakh")
for i, v in enumerate(m["revenue_lakh"]):
    ax.text(i, v + 0.1, f"{v:.1f}", ha="center", fontsize=8)
plt.show()
orders revenue_lakh month 2024-01 166 7.03 2024-02 128 5.24 2024-03 169 5.90 2024-04 139 4.32 2024-05 133 4.08 2024-06 134 5.02 2024-07 123 4.44 2024-08 180 4.92 2024-09 139 4.45 2024-10 249 8.61 2024-11 285 10.00 2024-12 155 4.80
Monthly revenue bar chart जिसमें October और November highlighted
Oct–Nov सबसे अलग – stock, staff और ad budget इन दो महीनों के लिए plan करें।
Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
m = df.groupby("month")["revenue"].sum()
festive = m[m.index.month.isin([10, 11])].sum()
print(f"Oct+Nov = {festive / m.sum() * 100:.1f}% of yearly revenue in {2 / 12 * 100:.0f}% of the time")
print("Best month:", m.idxmax(), "| weakest month:", m.idxmin())
Oct+Nov = 27.0% of yearly revenue in 17% of the time Best month: 2024-11 | weakest month: 2024-05

Q3: शहर और categories

Python
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_pickle("sales_ready.pkl")
city = df.groupby("city").agg(revenue=("revenue", "sum"), orders=("order_id", "count"), aov=("revenue", "mean"))
city["share_%"] = (city["revenue"] / city["revenue"].sum() * 100).round(1)
city = city.sort_values("revenue")
print(city.round(0).sort_values("revenue", ascending=False).head(5))
fig, ax = plt.subplots(1, 2, figsize=(12, 4.2))
(city["revenue"] / 1e5).plot(kind="barh", ax=ax[0], color="#4f46e5"); ax[0].set_title("Revenue by city (₹ lakh)")
cat = df.groupby("category")["revenue"].sum().sort_values()
ax[1].pie(cat, labels=cat.index, autopct="%1.0f%%", startangle=90, wedgeprops=dict(width=0.45))
ax[1].set_title("Revenue share by category")
plt.tight_layout(); plt.show()
revenue orders aov share_% city Mumbai 1043230.0 252 4140.0 15.0 Bengaluru 964020.0 299 3224.0 14.0 Delhi 945592.0 271 3489.0 14.0 Kolkata 839885.0 193 4352.0 12.0 Hyderabad 572190.0 200 2861.0 8.0
शहर के हिसाब से revenue का bar chart और category share का donut
Mumbai, Bengaluru और Delhi 40% से ज़्यादा revenue लाते हैं; अकेले Electronics कुल revenue का आधे से ज़्यादा।
Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
pv = df.pivot_table(index="category", values=["revenue", "quantity"], aggfunc="sum")
pv["orders"] = df.groupby("category").size()
pv["aov"] = (pv["revenue"] / pv["orders"]).round()
pv["rev_share_%"] = (pv["revenue"] / pv["revenue"].sum() * 100).round(1)
pv["order_share_%"] = (pv["orders"] / pv["orders"].sum() * 100).round(1)
print(pv[["orders", "order_share_%", "rev_share_%", "aov"]].sort_values("rev_share_%", ascending=False))
orders order_share_% rev_share_% aov category Electronics 439 22.0 55.8 8746.0 Fashion 486 24.3 22.0 3117.0 Grocery 528 26.4 11.5 1496.0 Home & Kitchen 325 16.2 6.2 1309.0 Books & Stationery 222 11.1 4.5 1396.0
🔎 इस table को पढ़ना

Grocery के orders बहुत हैं पर revenue share कम (कम AOV) – यह customers को बार-बार वापस लाता है। Electronics के orders कम पर पैसा सबसे ज़्यादा। दोनों ज़रूरी हैं, अलग वजहों से: frequency vs value।

Q4: क्या discounts काम करते हैं?

Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
d = df.groupby("disc_band", observed=True).agg(orders=("order_id", "count"), avg_qty=("quantity", "mean"),
                                               aov=("revenue", "mean"), rating=("rating", "mean"))
d["discount_given_₹"] = df.groupby("disc_band", observed=True).apply(
    lambda g: (g["quantity"] * g["unit_price"] * g["discount"]).sum(), include_groups=False).round()
print(d.round(2))
orders avg_qty aov rating discount_given_₹ disc_band None 794 1.95 3463.30 4.05 0.0 1-10% 529 1.98 3742.54 4.08 162403.0 11-20% 584 1.92 3162.97 4.05 422572.0 21-30% 93 1.86 3257.48 4.10 129834.0
💡 Insight

बड़े discounts से quantity per order और rating लगभग नहीं बदलते, पर दिया गया पैसा तेज़ी से बढ़ता है। इस data में भारी discounts ज़्यादातर margin घटाते हैं। सुझाव: छोटे, targeted offers test करें (Day 31 – A/B testing)।

Q5: हमारे customers कौन हैं?

Python
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_pickle("sales_ready.pkl")
fig, ax = plt.subplots(1, 2, figsize=(11, 3.8))
df.groupby("age_group", observed=True)["revenue"].sum().div(1e5).plot(kind="bar", ax=ax[0], color="#0891b2", rot=0)
ax[0].set_title("Revenue by age group (₹ lakh)")
pm = pd.crosstab(df["age_group"], df["payment_mode"], normalize="index") * 100
pm.plot(kind="bar", stacked=True, ax=ax[1], rot=0, colormap="Set2")
ax[1].set_title("Payment mode by age (%)"); ax[1].legend(fontsize=7, bbox_to_anchor=(1.01, 1), loc="upper left")
plt.tight_layout(); plt.show()
print(df.groupby("customer_gender")["revenue"].agg(["count", "mean"]).round())
count mean customer_gender Female 924 3244.0 Male 1076 3608.0
Age group के हिसाब से revenue और payment mode share
25–34 साल के लोग मुख्य customer हैं; हर age group में UPI सबसे आगे।

Q6: Customers कहाँ नाराज़ हैं?

Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
r = df.dropna(subset=["rating"])
low = r.assign(low=r["rating"] <= 3).groupby("product")["low"].agg(["mean", "count"])
low = low[low["count"] >= 30].sort_values("mean", ascending=False)
low["mean"] = (low["mean"] * 100).round(1)
print(low.rename(columns={"mean": "low_rating_%", "count": "orders"}).head(5))
print("Overall low-rating %:", round((r["rating"] <= 3).mean() * 100, 1))
low_rating_% orders product Power Bank 17.3 81 T-Shirt 17.3 110 Mobile Phone 16.3 104 Jeans 16.0 94 NCERT Book Set 15.8 38 Overall low-rating %: 12.4

Step 3: management summary

📈
Festive = पूरा सालOct–Nov साल के 17% समय में 27% revenue लाते हैं। Stock, delivery staff और ads 6 हफ़्ते पहले plan करें।
🏙️
पहले metrosMumbai, Bengaluru और Delhi 43% revenue लाते हैं। वहाँ same-day delivery मुख्य business बचाती है।
💸
हर किसी को discount बंदबड़े discounts से quantity या rating नहीं बढ़ी। Budget targeted offers पर लगाएँ।
🧑‍💻
25–34 + UPIमुख्य customer युवा है और UPI से pay करता है – UPI cashback, COD promotions से बेहतर।
2025 के लिए चार सुझाव
💼 इस project को कैसे present करें

इसे GitHub (Day 53) पर डालें: सवाल, notebook, 4–5 charts और README के ऊपर चार सुझाव। Recruiters पहले summary पढ़ते हैं – इसे code नहीं, business पर केंद्रित रखें।

🏅 आज के Job Skills

✔ Business सवाल बनाना✔ KPI table बनाना✔ groupby, pivot और charts से insights✔ Management के लिए सुझाव लिखना

Practice tasks

🏋️ Practice – ख़ुद करें

Task 1: Project आगे बढ़ाएँ: Q3 से Q4 में कौन सा region सबसे ज़्यादा बढ़ा?
Solution देखें
Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
q = df.pivot_table(index="region", columns=df["order_date"].dt.quarter, values="revenue", aggfunc="sum")
print(((q[4] / q[3] - 1) * 100).round(1).sort_values(ascending=False))
region East 106.6 South 99.2 West 55.5 North 37.4 dtype: float64
Task 2: हर शहर के revenue के हिसाब से top 3 products निकालें।
Solution देखें
Python
import pandas as pd
df = pd.read_pickle("sales_ready.pkl")
t = df.groupby(["city", "product"])["revenue"].sum().reset_index()
print(t.sort_values(["city", "revenue"], ascending=[True, False]).groupby("city").head(3).head(9).round(0).to_string(index=False))
city product revenue Ahmedabad Mobile Phone 112986.0 Ahmedabad Laptop 106274.0 Ahmedabad Sneakers 63819.0 Bengaluru Mobile Phone 264752.0 Bengaluru Laptop 141908.0 Bengaluru Sneakers 98781.0 Chennai Mobile Phone 160087.0 Chennai Laptop 114432.0 Chennai Sneakers 45284.0
Task 3: Data के एक number के साथ अपना पाँचवाँ सुझाव लिखें।

Quick quiz

🧠 Quick Quiz – ख़ुद को जाँचें

1. AOV का मतलब…
Revenue ÷ orders की संख्या।
2. साफ़ data को pickle में क्यों save करें?
CSV dates और categories को फिर text बना देता।
3. अच्छी management summary…
हर बात: finding + number + action।
4. Grocery का order share ज़्यादा पर revenue share कम। मतलब…
बहुत सारी छोटी baskets।
5. Discounts “काम करते हैं” या नहीं, जाँचने के लिए किसकी तुलना करें?
फ़ायदे को cost से तौलना होगा। Cause A/B test से साबित होता है।

Interview corner

💼 Interview Corner

अपने किसी data analysis project के बारे में बताइए।

STAR लें: Situation (CEO को 2024 review चाहिए था), Task (drivers और मौके ढूँढना), Action (2,000 orders साफ़ किए, pandas में KPIs, trend, city/category/discount/customer analysis), Result (चार सुझाव, जैसे festive season = revenue का X%, भारी discounts से quantity नहीं बढ़ी)।

क्या आप कह सकते हैं कि discounts से कोई बदलाव नहीं हुआ?

नहीं – यह observational data है; discounts random नहीं थे। यह सिर्फ़ hypothesis देता है। कारण साबित करने के लिए controlled A/B test चाहिए।

सारांश

  • Charts से नहीं, business सवालों से शुरू करें।
  • एक load/clean function + saved pickle analysis को एक जैसा रखता है।
  • हर सवाल → table → chart → एक line की insight।
  • 3–5 actionable, numbers वाले सुझावों से ख़त्म करें।
➡️ आगे

Day 20: Pandas practice test – 15 असली tasks यह जाँचने के लिए कि आप pandas में job-ready हैं।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

क्या यह project portfolio में डाल सकते हैं?
हाँ – पर अपना सवाल और सुझाव जोड़ें ताकि यह सच में आपका हो, और README में अपने फ़ैसले समझाएँ।
Notebook या script?
Exploration और presentation के लिए notebook; project बढ़ने पर reusable code (load_sales) .py file में रखें।
← Data Science (60 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

अगला topicदिन 20: Revision Test: Python + Pandas आपकी प्रगति: 19 / 60 (32%) · Lesson 20 / 60 आगे बढ़ें →

यह lesson कैसा लगा?

आपकी राय से हम content और बेहतर बनाते हैं।

अपना review और सुझाव लिखें (वैकल्पिक)

Review approve होने के बाद आपका नाम और शहर इसके साथ public दिख सकते हैं। Email या phone न लिखें।

▶ CodingEasily on YouTube

Video से सीखें – आसान Hindi में

चुनी हुई video: RDBMS भाग 3 – Class XI Commerce IT

▶ Channel subscribe करें