2025, Sep 25 05:32
pandas में groupby, nunique और count से यूनिक क्लास नाम और उनके काउंट
इस गाइड में pandas groupby के साथ nunique और count से वे नाम पाएँ जिनकी क्लास हर जगह एक ही हो, साथ ही उसी नाम–क्लास जोड़ी की आवृत्ति भी जानें, उदाहरण सहित.
जब आपको किसी श्रेणीबद्ध कॉलम में ठीक एक मान पर मैप होने वाले सभी नाम ढूंढ़ने हों और साथ ही यह दिखाना हो कि प्रत्येक नाम–क्लास जोड़ी कितनी बार आती है, तो pandas में सबसे सीधा तरीका एक ही चरण में एग्रीगेट करके फ़िल्टर करना है। नीचे दिया गया संक्षिप्त पैटर्न मैन्युअल पोस्ट-प्रोसेसिंग से बचाता है और प्रतिनिधि मान के साथ उसकी आवृत्ति भी देता है।
समस्या की रूपरेखा
हमारे पास एक ऐसा डेटासेट है जिसमें नाम बार-बार आते हैं और उनके साथ उनकी क्लास दी गई है। काम यह है कि केवल वही नाम लौटाएँ जिनके लिए सभी पंक्तियों में क्लास एक ही हो, और उस नाम–क्लास के लिए आने की संख्या (count) वाली कॉलम भी शामिल करें। कोई नाम अगर सिर्फ एक बार आता है, तो वह भी यूनिक माना जाएगा।
पुनरुत्पाद्य उदाहरण
निम्न कोड DataFrame बनाता है और पहला तरीका दिखाता है, जो प्रति नाम यूनिक क्लासों को सूचीबद्ध करता है:
import pandas as pd
records = {
    'name':  ['Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'Nick', 'Jane', 'Jacon', 'Jack', 'Cooze', 'John'],
    'class': ['a',    'b',     'a',    'b',    'a',     'b',    'b',    'c',     'a',    'a',     'a']
}
frame = pd.DataFrame(records)
by_name_unique = frame.groupby('name')['class'].unique()
print(by_name_unique)
यह प्रत्येक नाम के लिए यूनिक क्लास मान तो दे देता है, लेकिन लंबाई निकालना और फिर हाथ से फ़िल्टर करना आपके ऊपर छोड़ देता है—जो न केवल अनावश्यक है, बल्कि त्रुटि-प्रवण भी।
असल में हो क्या रहा है
.unique() कॉल प्रत्येक समूह के लिए भिन्न मानों की arrays लौटाता है। यह तय करने के लिए कि किसी नाम की ठीक एक ही क्लास है या नहीं, मकसद यह देखना है कि उस नाम की अलग-अलग क्लासों की संख्या कितनी है। यही काम .nunique() करता है। इसके अलावा, आपको उस नाम–क्लास जोड़ी की आवृत्ति भी चाहिए, जो उसी समूह के भीतर सरलतापूर्वक .count() से मिल जाती है। इन एग्रीगेशनों को साथ लाने से कई पास और उलझी हुई array-लंबाई जाँचों से बचा जा सकता है।
समाधान
समेकित करें, भिन्न-क्लास की गिनती पर फ़िल्टर करें, और केवल प्रासंगिक कॉलम रखें। नीचे का स्निपेट सिर्फ़ उन्हीं नामों को लौटाता है जिनकी एक ही क्लास है, साथ में वही क्लास मान और उसकी आवृत्ति। जो नाम केवल एक बार आते हैं, वे भी शामिल हैं क्योंकि उनकी distinct-क्लास गिनती 1 होती है।
result = (
    frame.groupby('name')['class']
         .agg([('class', 'first'), 'nunique', 'count'])
         .query('nunique == 1')
         .drop(columns='nunique')
)
print(result)
ऊपर दिए गए डेटा के साथ अपेक्षित आउटपुट में वे प्रविष्टियाँ दिखती हैं जहाँ हर नाम की ठीक एक ही क्लास है, और साथ में यह भी कि वह कितनी बार आता है:
       class  count
name                
Cooze      a      2
Jane       b      2
John       a      1
यह क्यों मायने रखता है
.nunique() और .agg() पर भरोसा करना arrays बनाकर उनकी लंबाइयाँ निकालने से अधिक स्पष्ट और तेज़ है। यह तर्क को घोषणात्मक रखता है: एक बार group करें, जो चाहिए वही गणना करें, फ़िल्टर करें, और परिणाम दिखा दें। यह पैटर्न बड़े डेटासेट पर बेहतर स्केल करता है क्योंकि यह Python-स्तर के लूप या सूची-हैंडलिंग से बचता है और pandas को अंदर ही अंदर वेक्टराइज़्ड ऑपरेशनों का लाभ उठाने देता है।
मुख्य सीख
जब भी pandas में आपको समूह के भीतर “यूनिक” जाँच और काउंट दोनों चाहिए, तो बीच के .unique() arrays को छोड़ दें। सीधे .groupby(...).agg(...) पर जाएँ—distinctness के लिए nunique और आवृत्ति के लिए count लें, nunique == 1 पर फ़िल्टर करें, और वे ही कॉलम रखें जो महत्वपूर्ण हों। यह संक्षिप्त, स्पष्ट और उन डेटासेट्स के लिए मज़बूत है जहाँ नाम अलग-अलग क्लास मानों के साथ दोहर सकते हैं।