2025, Oct 16 13:31

delimiter और whitespace के साथ pandas स्ट्रिंग नॉर्मलाइज़ेशन

pandas में '; ' से विभाजित स्ट्रिंग्स को स्थिर रूप में लाने का तरीका जानें: सही delimiter से split करें, whitespace normalize करें, टोकन sort करें और उसी से join करें.

स्ट्रिंग कॉलम के भीतर delimiter से अलग किए गए टोकन को सॉर्ट करना उतना आसान नहीं जितना दिखता है: ज़रा‑सी whitespace घुस आए तो क्रम बिगड़ जाता है। अगर आप pandas में टेक्स्ट फ़ील्ड्स को नॉर्मलाइज़ कर रहे हैं और हर जगह “bar; foo” जैसा एकसमान, वर्णानुक्रमित रूप चाहते हैं, तो delimiter के वास्तविक रूप में छोटी‑सी असंगति भी नतीजों को उलट सकती है।

समस्या

हमारे पास एक DataFrame है, जिसकी एक कॉलम में सेमीकोलन से विभाजित स्ट्रिंग्स हैं। उद्देश्य यह है कि हर स्ट्रिंग के भीतर के टोकन को वर्णानुक्रम में रखकर हर पंक्ति को एक ही मान पर नॉर्मलाइज़ किया जाए।

import pandas as pd

tbl = pd.DataFrame({'pair_col': ['foo; bar', 'foo; bar', 'bar; foo']})

print(tbl)
# pair_col
# 0 foo; bar
# 1 foo; bar
# 2 bar; foo

वांछित परिणाम यह है कि हर पंक्ति “bar; foo” बन जाए।

एक कोशिश जो सही दिखती है, पर सही नहीं

आम तौर पर हम split, sort और फिर join कर देते हैं। लेकिन अगर आपने गलत delimiter पर split किया, तो बीच के टोकन अपने शुरुआती स्पेस संभाले रखेंगे और क्रम पर असर पड़ेगा।

result = tbl.pair_col.str.split(';').apply(sorted).apply(lambda parts: ';'.join(parts))
print(result)
# 0 bar;foo
# 1 bar;foo
# 2 foo;bar

एक पंक्ति जो पहले से सही क्रम में थी, “foo;bar” बन जाती है। यह संकेत है कि sort ने वही टोकन आपस में नहीं तुलना किए जिसकी उम्मीद थी।

ऐसा क्यों होता है

स्ट्रिंग्स में वास्तविक सेपरेटर “; ” है, यानी सेमीकोलन के बाद एक स्पेस। सिर्फ “;” पर split करने से ऐसे टोकन बनते हैं: ["foo", " bar"]। दूसरे टोकन के साथ अग्रणी स्पेस जुड़ा रह जाता है। जब आप इन्हें शब्दकोशीय क्रम में sort करते हैं, तो " bar" "bar" के बराबर नहीं होता; स्पेस भी तुलना में भाग लेता है और वे तत्व हिल सकते हैं जिन्हें आप स्थिर मान रहे थे। बाद में join बिना स्पेस के टोकन चिपका देता है, जिससे मूल whitespace समस्या छिप जाती है और आउटपुट असंगत दिखता है।

समाधान

सही delimiter पर split करें ताकि टोकन साफ हों, उन्हें sort करें और उसी delimiter से दोबारा जोड़ें। इससे whitespace सुसंगत रहता है और sort सार्थक बनता है।

import pandas as pd

tbl = pd.DataFrame({'pair_col': ['foo; bar', 'foo; bar', 'bar; foo']})

tbl['pair_col'] = (tbl['pair_col']
.str.split('; ')
.apply(lambda chunks: sorted(chunks))
.apply(lambda chunks: '; '.join(chunks)))

# यदि आप पंक्तियों को भी normalized स्ट्रिंग के अनुसार क्रमबद्ध करना चाहते हैं, तो:
# tbl.sort_values('pair_col', inplace=True)

print(tbl)
# pair_col
# 0 bar; foo
# 1 bar; foo
# 2 bar; foo

यह क्यों मायने रखता है

डेटा नॉर्मलाइज़ेशन सटीक delimiter और whitespace नियंत्रण पर टिका होता है। एक छोटा‑सा अतिरिक्त स्पेस भी sort के अर्थ बदल देता है और आगे की तुलना, डीडुप्लिकेशन और joins बिगाड़ सकता है। सेपरेटर को स्पष्ट रखना और दोबारा जोड़ते समय उसी को बनाए रखना पूर्वानुमेय, एकरूप स्ट्रिंग्स देता है। यदि परफॉर्मेंस चिंता का विषय है, तो पाइपलाइन में पहले ही (जैसे DataFrame बनाने से पहले) sort करना ज़्यादा कुशल हो सकता है; परीक्षणों में इस तरीके से लगभग 135% का सुधार दिखा।

मुख्य बातें

delimiter को लेकर सटीक रहें। अगर सेपरेटर “; ” है, तो सिर्फ “;” पर split न करें। साफ टोकन सूची को sort करें और उसी delimiter से फिर जोड़ें ताकि फ़ॉर्मेटिंग स्थिर रहे। यह छोटी‑सी सावधानी सूक्ष्म क्रम संबंधी बग्स से बचाती है और पूरे डेटासेट में स्ट्रिंग नॉर्मलाइज़ेशन भरोसेमंद बनाती है।

यह लेख StackOverflow पर प्रश्न (लेखक: bismo) और LMC के उत्तर पर आधारित है।