2025, Oct 31 08:01
CSV की जगह सीधा लिखें: pandas groupby से कस्टम टेक्स्ट आउटपुट
इस गाइड में pandas से CSV to_csv की सीमाएँ समझें और ID पर groupby कर के कस्टम टेक्स्ट आउटपुट सीधे फ़ाइल में लिखना सीखें। साफ़, बिना उद्धरण वाला, तेज़, सटीक परिणाम पाएँ।
जब लक्ष्य प्रारूप CSV तालिका नहीं, बल्कि मुक्त-रूप पाठ हो, तो आउटपुट को CSV राइटर से गुजारना अक्सर उल्टा पड़ता है। समूहित मान उद्धृत कोशिकाओं के भीतर धंस जाते हैं, कॉमा घुस आते हैं, और पंक्ति-विराम मनचाही जगह पर नहीं आते। यदि आपका उद्देश्य ऐसा सादा-पाठ लेआउट है जिसमें ID शीर्षक हो, उसके बाद उसकी पंक्तियाँ और एक विभाजक, तो pandas.to_csv का उपयोग करने के बजाय फ़ाइल को सीधे लिखने से परिणाम कहीं अधिक साफ़ मिलेगा।
समस्या का सेटअप
हमें ID और OTHER_FIELDS_2 स्तंभों वाला CSV पढ़ना है, ID के आधार पर समूह बनाना है, और एक ऐसी टेक्स्ट फ़ाइल बनानी है जिसमें हर समूह ID से शुरू हो, फिर OTHER_FIELDS_2 के गैर-खाली मान सूचीबद्ध हों, और अंत में तारांकितों की एक पंक्ति हो। इस लेआउट के लिए DataFrame-से-CSV फ़ॉर्मैटिंग करने पर अतिरिक्त उद्धरण चिह्न और ग़लत जगह पर लाइन ब्रेक आ जाते हैं।
वह कोड जो फ़ॉर्मैटिंग समस्या पैदा करता है
नीचे दिया गया स्निपेट पंक्तियों को समूहित करता है, समूहित डेटा को स्ट्रिंग में बदलता है, और फिर to_csv के जरिए लिखता है। तर्क स्पष्ट है, पर अंतिम लिखने का चरण गैर-CSV प्रारूप पर CSV के नियम थोप देता है; इसी कारण आउटपुट में उद्धरण चिह्न और अवांछित कलाकृतियाँ दिखाई देती हैं।
import pandas as pd
import csv
tbl = pd.read_csv('idDetails.csv')
row_buffer = []
key_col = 'ID'
value_cols = ['OTHER_FIELDS_2']
clusters = tbl.groupby(key_col)[value_cols]
for k, sub in clusters:
    lines_as_is = sub.to_string(header=False, index=False)
    cleaned = sub.fillna('').dropna(axis=0, how='all')
    flat_text = cleaned.to_string(header=False, index=False)
    sep_line = '**********'
    row_buffer.append([k, '\n', flat_text, '\n', sep_line])
out = pd.DataFrame(row_buffer)
out.to_csv('idDetailsoutput.txt', header=False, index=False)
सादे पाठ के लिए यह क्यों विफल होता है
पंक्तियाँ एक DataFrame में इकट्ठी की जाती हैं और to_csv से निर्यात होती हैं, जो सुव्यवस्थित CSV तालिका बनाने के लिए बना है। इसका मतलब है कि फ़ील्ड्स को CSV की शुद्धता के लिए उद्धृत और अलग किया जाता है। चूँकि हर समूह वस्तुतः बहु-पंक्तीय पाठ वाली एक ही पंक्ति बन जाता है, राइटर उसे उद्धरण में लपेटकर और लाइन ब्रेक को एक सेल के भीतर समेटकर संरक्षित करता है, जिससे अतिरिक्त उद्धरण और असहज लेआउट बनता है। CSV स्तंभों के मानों वाली आयताकार तालिका की अपेक्षा करता है, जबकि वांछित आउटपुट एक कस्टम टेक्स्ट लेआउट है।
प्रत्यक्ष-लिखाई समाधान
इस कार्य के लिए DataFrame-से-CSV चरण छोड़ दें। समूहों पर इटरेट करें और जितनी ज़रूरत हो उतना सीधे टेक्स्ट फ़ाइल में लिखें। इससे CSV के उद्धरण नियम पूरी तरह बच जाते हैं और फ़ॉर्मैटिंग आपके नियंत्रण में रहती है।
import pandas as pd
# इनपुट पढ़ें
records = pd.read_csv('idDetails.csv')
# ID के आधार पर समूह बनाएं और लक्षित स्तंभ चुनें
by_id = records.groupby('ID')['OTHER_FIELDS_2']
# कस्टम टेक्स्ट आउटपुट लिखें
with open('idDetailsoutput.txt', 'w') as out_f:
    for gid, series in by_id:
        out_f.write(f"{gid}\n")
        for val in series:
            if pd.notna(val) and val.strip() != "":
                out_f.write(f"{val.strip()}\n")
        out_f.write("**********\n")
प्राप्त आउटपुट अनुरोधित प्रारूप से मेल खाता है:
18
20 BA-10  12  06  2  30  S
20 BA-20  12  06  2  30  S
**********
66
20 AD-38  12  06  B
20 AD-38  30  07  B
**********
70
20 OL-45  19  11  B
20 EM-45  19  08  B
**********
77
**********
87
25 R160  22  13  E
25 R165  22  08  E
**********
88
20 TH-42  02  02  5  30  MT
**********
यह जानना क्यों उपयोगी है
pandas से डेटा तैयार करते समय भी हर आउटपुट को CSV होना ज़रूरी नहीं। यदि अंतिम परिणाम मानव-पठनीय, संरचित टेक्स्ट ब्लॉक है, तो साधारण write से आपको सटीक नियंत्रण मिलता है और CSV के उद्धरण, कॉमा और सेल सीमाएँ आपके अंतिम लेआउट में घुसपैठ नहीं करतीं।
मुख्य बातें
रिकॉर्ड को व्यवस्थित करने के लिए groupby का उपयोग करें, पर आउटपुट विधि वही चुनें जो आपके वांछित प्रारूप से मेल खाती हो। कस्टम टेक्स्ट लेआउट के लिए पंक्तियाँ सीधे लिखें और चलते-चलते खाली मानों को हटा दें। इससे आउटपुट साफ़, पूर्वानुमेय और आपकी विनिर्देश के अनुरूप रहता है।
यह लेख StackOverflow पर प्रश्न (लेखक: learner) और codewithpurpose के उत्तर पर आधारित है।