2025, Oct 21 05:32
pandas groupby में Series alignment: क्या, क्यों और कैसे
जानें कि pandas groupby में Series को grouper बनाते समय index alignment कैसे काम करता है, mismatched indices पर डेटा गिरता है, और सही grouping के लिए करें.
किसी pandas Series को दूसरी Series के आधार पर समूहित करना सीधा-सा लगता है, जब तक कि index alignment बीच में दखल न दे। यदि आप एक Series को grouper के रूप में पास करते हैं और उसका index बिना ध्यान दिए बदल देते हैं, तो बने समूह बेतुके लग सकते हैं। यह व्यवहार जान-बूझकर है: pandas, Series के मानों को group keys की तरह उपयोग करने से पहले index labels के आधार पर alignment करता है। इस एक नियम को समझ लेना, स्क्रीन पर दिख रही हर चीज़ को स्पष्ट कर देता है।
समस्या को पुन: उत्पन्न करना
नीचे दिए गए सेटअप में पहले Series को स्वयं से group किया गया है, और फिर उसी Series के reset index वाले संस्करण से। दूसरा मामला वहीं है, जहाँ चीज़ें “टूटी हुई” लगती हैं।
import numpy as np
import pandas as pd
# मूल Series
data_s = pd.Series([10, 10, 20, 30, 30, 30], index=np.arange(6) + 2)
print(data_s)
# 2    10
# 3    10
# 4    20
# 5    30
# 6    30
# 7    30
# dtype: int64
# उसी Series से group करना (अपेक्षित)
bins_1 = data_s.groupby(data_s)
for grp_key, grp_vals in bins_1:
    print(f"Group: {grp_key}")
    print(grp_vals)
# Group: 10
# 2    10
# 3    10
# dtype: int64
# Group: 20
# 4    20
# dtype: int64
# Group: 30
# 5    30
# 6    30
# 7    30
# dtype: int64
# वही मान grouper के रूप में, लेकिन reset index के साथ (चौंकाने वाला परिणाम)
key_s = data_s.reset_index(drop=True)
bins_2 = data_s.groupby(key_s)
for grp_key, grp_vals in bins_2:
    print(f"Group: {grp_key}")
    print(grp_vals)
# Group: 20.0
# 2    10
# dtype: int64
# Group: 30.0
# 3    10
# 4    20
# 5    30
# dtype: int64वास्तव में क्या हो रहा है
यह व्यवहार इस बात से तय होता है कि pandas, groupby में “by” तर्क को कैसे समझता है। दस्तावेज़ कहता है:
by : mapping, function, label, pd.Grouper या इनका list
groupby के लिए समूह तय करने में उपयोग होता है। यदि
byएक function है, तो इसे ऑब्जेक्ट के index के प्रत्येक मान पर बुलाया जाता है। यदि कोईdictयाSeriesपास की जाती है, तो समूह तय करने के लिए उसीSeriesयाdictके VALUES का उपयोग होता है (Series के मान पहले aligned किए जाते हैं;.align()विधि देखें)।
मुख्य शब्द है aligned। जब आप Series को grouper की तरह पास करते हैं, तो pandas पहले उस Series को जिस ऑब्जेक्ट पर group कर रहे हैं उसके साथ index labels के आधार पर align करता है, और उसके बाद aligned मानों को group keys मानता है। इसका मतलब grouping position-आधारित नहीं, label-आधारित होती है। यदि labels नहीं मिलते, तो जो labels ओवरलैप नहीं करते वहाँ NaN आता है, और क्योंकि NaN एक वैध group key नहीं है, वे पंक्तियाँ चुपचाप grouping से गिर जाती हैं।
उदाहरण में, मूल Series के index labels 2, 3, 4, 5, 6, 7 हैं। reset-index वाले grouper के labels 0, 1, 2, 3, 4, 5 हैं। इनको labels पर align करने से 2–5 के लिए ही keys मिलती हैं और 6–7 के लिए NaN आता है। इसी वजह से समूह अंततः केवल 20.0 और 30.0 बनते हैं, और 6 तथा 7 के लिए कुछ नहीं होता।
Alignment को स्पष्ट रूप से देखना
Alignment को आंखों के सामने लाने से मानसिक मॉडल पक्का हो जाता है। मूल Series को reset-index वाली Series के साथ index पर join करें, और फिर aligned कॉलम पर group करें।
# index-आधारित join के जरिए alignment को देखें
aligned = (
    data_s.rename("col_src").to_frame()
    .join(key_s.rename("col_key"))
)
print(aligned)
#    col_src  col_key
# 2       10     20.0
# 3       10     30.0
# 4       20     30.0
# 5       30     30.0
# 6       30      NaN
# 7       30      NaN
# aligned key कॉलम पर group करें
for grp_key, grp_df in aligned.groupby("col_key"):
    print(f"Group: {grp_key}")
    print(grp_df)
# Group: 20.0
#    col_src  col_key
# 2       10     20.0
# Group: 30.0
#    col_src  col_key
# 3       10     30.0
# 4       20     30.0
# 5       30     30.0समाधान को कैसे समझें
समाधान अवधारणात्मक है: याद रखें कि groupby के grouper के रूप में दी गई Series को लक्ष्य ऑब्जेक्ट के साथ उसके index के आधार पर realign किया जाता है। grouper का index बदलने से alignment के बाद बनने वाली keys बदल जाती हैं। यदि आपका यही इरादा नहीं है, तो grouping से पहले grouper का index न बदलें। शंका हो तो, ऊपर दिखाए अनुसार alignment को स्पष्ट रूप से बनाएं और group करने से पहले उस मध्यवर्ती संरचना को देख लें।
यह क्यों मायने रखता है
Index alignment, pandas की सबसे शक्तिशाली और महीन विशेषताओं में से एक है। लाइब्रेरी वही कर रही होती है जिसका वह वादा करती है, फिर भी नतीजे को अक्सर लोग बग समझ लेते हैं। mismatched indices के साथ group करने पर डेटा चुपचाप गिर सकता है या पंक्तियाँ अनपेक्षित buckets में चली जा सकती हैं। इसकी कीमत उस समय से चुकानी पड़ती है जो हम “रैंडम” दिखने वाले, मगर वास्तव में निर्धारक व्यवहार को डिबग करने में खो देते हैं।
मुख्य बातें
groupby को Series पास करते समय, मान index द्वारा alignment के बाद ही उपयोग में आते हैं। यदि आपके समूह गलत लग रहे हों, तो दोनों तरफ के indices जाँचें, या join के साथ alignment चरण को फिर से बनाकर देख लें कि pandas वास्तव में किन keys पर group कर रहा है। index labels को प्राथमिक दर्जे का मानें—अधिकांश आश्चर्यों से बचेंगे।