दिन 14: Merge, Join और Concat
✅ आज आप सीखेंगे
- असली data कई tables में क्यों होता है
- merge: inner, left, right, outer
- अलग key names, indicator और validate
- concat: monthly files एक के नीचे एक
- Duplicate rows के धमाके से बचना
🏢 असली दुनिया में
HR employees को एक system में और departments को दूसरे में रखता है; finance हर महीने salaries नई file में भेजता है। “हर department और शहर की औसत salary” बताने के लिए इन tables को सही से join और stack करना होता है – ग़लत join चुपचाप आपके numbers दोगुने कर देता है।
हमारी दो tables
import pandas as pd
emp = pd.read_csv("employees.csv")
dept = pd.read_csv("departments.csv")
print(emp.head(6))
print(dept)
print("Employee dept_ids:", sorted(emp["dept_id"].unique()))Join के प्रकार
| how= | क्या रखता है | आम इस्तेमाल |
|---|---|---|
| inner | दोनों में match वाली rows | Matched records का साफ़ analysis |
| left | Left table की सभी rows | Main table में details जोड़ना (सबसे आम) |
| right | Right table की सभी rows | कम – tables बदलकर left लें |
| outer | दोनों से सब कुछ | किसी भी तरफ़ क्या missing है, ढूँढना |
merge का इस्तेमाल
import pandas as pd
emp = pd.read_csv("employees.csv")
dept = pd.read_csv("departments.csv")
inner = emp.merge(dept, on="dept_id", how="inner")
left = emp.merge(dept, on="dept_id", how="left")
outer = emp.merge(dept, on="dept_id", how="outer", indicator=True)
print("emp:", len(emp), "| inner:", len(inner), "| left:", len(left), "| outer:", len(outer))
print(left[left["dept_name"].isna()][["emp_id", "name", "dept_id"]])
print(outer["_merge"].value_counts())दो employees department 60 के हैं, जो departments table में है ही नहीं। Inner join उन्हें चुपचाप हटा देता – report से पहले हमेशा unmatched rows जाँचें।
import pandas as pd
emp = pd.read_csv("employees.csv")
dept = pd.read_csv("departments.csv")
full = emp.merge(dept, on="dept_id", how="left", suffixes=("_emp", "_dept"))
full["dept_name"] = full["dept_name"].fillna("Unassigned")
report = full.groupby("dept_name").agg(people=("emp_id", "count"), avg_salary=("salary", "mean")).round(0)
print(report.sort_values("avg_salary", ascending=False))
print(full[["name", "city", "location"]].head(3)) # city = where the person livesअलग key names और validation
import pandas as pd
orders = pd.DataFrame({"order_id": [1, 2, 3, 4], "cust": ["C1", "C2", "C1", "C9"], "amount": [450, 1299, 780, 320]})
customers = pd.DataFrame({"customer_id": ["C1", "C2", "C3"], "name": ["Riya", "Om", "Zoya"], "city": ["Pune", "Delhi", "Agra"]})
m = orders.merge(customers, left_on="cust", right_on="customer_id", how="left", validate="many_to_one")
print(m)import pandas as pd
orders = pd.DataFrame({"cust": ["C1", "C2"], "amount": [450, 1299]})
dirty_customers = pd.DataFrame({"cust": ["C1", "C1", "C2"], "city": ["Pune", "Pune", "Delhi"]}) # C1 duplicated!
bad = orders.merge(dirty_customers, on="cust")
print("Orders:", len(orders), "-> after merge:", len(bad), "| total amount doubled to", bad["amount"].sum())
try:
orders.merge(dirty_customers, on="cust", validate="many_to_one")
except Exception as e:
print("validate caught it:", type(e).__name__)Lookup table में duplicate keys हों तो merge rows को गुणा कर देता है और totals चुपचाप बढ़ जाते हैं। validate="many_to_one" लिखें, या पहले lookup table पर drop_duplicates("key"), और merge से पहले-बाद row counts मिलाएँ।
concat: files एक के नीचे एक
import pandas as pd
sales = pd.read_csv("sales_data.csv")
for m in ["01", "02", "03"]: # pretend finance sent 3 monthly files
sales[sales["order_date"].str[5:7] == m].to_csv(f"sales_2024_{m}.csv", index=False)
files = [f"sales_2024_{m}.csv" for m in ["01", "02", "03"]]
q1 = pd.concat([pd.read_csv(f).assign(source=f) for f in files], ignore_index=True)
print(q1.shape)
print(q1["source"].value_counts().sort_index())import pandas as pd
a = pd.DataFrame({"maths": [78, 92]}, index=["Aman", "Priya"])
b = pd.DataFrame({"science": [82, 88]}, index=["Aman", "Priya"])
print(pd.concat([a, b], axis=1)) # side by side on the index
print(a.join(b)) # same thing with joinअसली example: location के हिसाब से salary report
import pandas as pd
emp = pd.read_csv("employees.csv")
dept = pd.read_csv("departments.csv")
before = len(emp)
df = emp.merge(dept, on="dept_id", how="left", validate="many_to_one")
assert len(df) == before, "row count changed – check keys!"
df["dept_name"] = df["dept_name"].fillna("Unassigned")
pv = df.pivot_table(index="dept_name", columns="location", values="salary", aggfunc="mean").round(-3)
print(pv.fillna("-"))
print("\nHighest paid per department:")
print(df.loc[df.groupby("dept_name")["salary"].idxmax(), ["dept_name", "name", "salary"]].to_string(index=False))🏅 आज के Job Skills
Practice tasks
🏋️ Practice – ख़ुद करें
Solution देखें
import pandas as pd
emp = pd.read_csv("employees.csv"); dept = pd.read_csv("departments.csv")
m = dept.merge(emp, on="dept_id", how="left", indicator=True)
print(m[m["_merge"] == "left_only"]["dept_name"].tolist() or "Every department has employees")Solution देखें
import pandas as pd
emp = pd.read_csv("employees.csv"); dept = pd.read_csv("departments.csv")
df = emp.merge(dept, on="dept_id", how="inner")
df["dept_avg"] = df.groupby("dept_name")["salary"].transform("mean")
print(df[df["salary"] > df["dept_avg"]][["name", "dept_name", "salary"]].to_string(index=False))students_performance.csv को Government और Private files में बाँटें, फिर concat करके row count जाँचें।Quick quiz
🧠 Quick Quiz – ख़ुद को जाँचें
Interview corner
💼 Interview Corner
कैसे जाँचेंगे कि join ने duplicates नहीं बनाए?
पहले और बाद की row count मिलाएँ (many-to-one left join में left table के बराबर होनी चाहिए), validate="many_to_one" लगाएँ, और df.key.is_unique या duplicated() से lookup key unique जाँचें।
merge और concat में क्या फ़र्क है?
merge key values मिलाकर tables को साथ-साथ जोड़ता है (SQL JOIN जैसा)। concat tables को एक axis पर stack करता है – आमतौर पर एक जैसे columns वाली rows, SQL UNION ALL जैसा।
सारांश
- merge(on=..., how=inner/left/right/outer) SQL जैसा join करता है।
- indicator=True unmatched rows दिखाता है।
- validate="many_to_one" और row-count checks आपके totals बचाते हैं।
- concat files stack करता है; join/concat(axis=1) index पर जोड़ते हैं।
Week 3 शुरू! Day 15: data cleaning – missing values, duplicates, ग़लत types और असंभव values।
