2025, Oct 04 05:31
pandas में डिक्शनरी/JSON कॉलम को id–schedule_name long तालिका में बदलने की साफ पाइपलाइन
pandas में nested JSON/डिक्शनरी कॉलम को long-form DataFrame में बदलें: keys को कॉलम बनाकर stack व reset_index से id और schedule_name की साफ मैपिंग पाएँ.
नेस्टेड JSON को एक साफ, विश्लेषण के लिए तैयार तालिका में समतल करना अक्सर करना पड़ता है। एक आम स्थिति: pandas की किसी कॉलम में ऐसी डिक्शनरी होती हैं, जिनमें keys पहचानकर्ता (identifiers) हैं और values पढ़ने योग्य लेबल। लक्ष्य यह है कि सभी पंक्तियों में मौजूद हर key–value जोड़ी को id और schedule_name वाले दो-स्तंभों के सुव्यवस्थित dataframe में बदल दिया जाए। दिक्कत अक्सर तब होती है जब यह रूपांतरण पूरे कॉलम पर सही तरह लागू करना हो, सिर्फ किसी एक पंक्ति पर नहीं।
शुरुआती स्थिति
मान लीजिए एक dataframe कॉलम में हर पंक्ति पर शेड्यूल मैपिंग वाली डिक्शनरी हैं। मोटे तौर पर यह कुछ ऐसा दिखेगा:
tbl['schedules']
0  {'3263524': 'Group 1 CORE DAYS', '3263525': 'Group 1 CORE NIGHTS', '3263526': 'Group 1 EDUCATION', '3263527': 'Group 1 ROUNDING'}
1  {'3263524': 'Group 1 CORE DAYS', '3881368': 'VS Days', '3881370': 'VS Education Shift A', '3881455': 'VS Education Shift B'}
लक्षित long-form dataframe में किसी भी पंक्ति की डिक्शनरी से निकली हर जोड़ी के लिए एक पंक्ति होनी चाहिए:
id        schedule_name
3263524   Group 1 CORE DAYS
3263525   Group 1 CORE NIGHTS
3263526   Group 1 EDUCATION
3263527   Group 1 ROUNDING
3881368   VS Days
3881370   VS Education Shift A
3881455   VS Education Shift B
एक सरल लेकिन अधूरा प्रयास
मन करता है कि from_dict को किसी एक डिक्शनरी पर चला दें, पर यह सिर्फ एक ही पंक्ति संभालता है और हमें चाहिए वैसा कॉलम नाम या इंडेक्स भी नहीं बनाता:
sched_map = pd.DataFrame.from_dict(tbl['schedules'].iloc[0], orient='index')यह तरीका बाकी सभी पंक्तियों को अनदेखा कर देता है और अंत में सही कॉलम नाम और एकसमान इंडेक्स पाने के लिए अतिरिक्त मेहनत भी करनी पड़ती है।
असल में करना क्या है
साफ-सुथरा समाधान सभी डिक्शनरी keys को पंक्तियों के पार मिलाकर उन्हें कॉलम की तरह संरेखित करने से शुरू होता है। डिक्शनरी की श्रृंखला (series) को एक wide dataframe में बदलना यही करता है: हर यूनिक key अपने अलग कॉलम में चली जाती है, और किसी पंक्ति में key न होने पर वहाँ NaN भरता है। इसके बाद stack लगाने से डेटा long फॉर्मेट में आ जाता है, ताकि हर key–value जोड़ी अपनी अलग पंक्ति बन जाए। stacked इंडेक्स-लेवल को नीचे एक कॉलम में लाने से डिक्शनरी keys वास्तविक डेटा के रूप में दिखने लगती हैं। फिर इन दो कॉलमों का नामकरण टेबल को सलीके से पूरा करता है, और duplicates हटाने से दोहराई गई जोड़ियाँ समेट दी जाती हैं।
समाधान
यह केवल pandas वाला पाइपलाइन सब कुछ साथ जोड़ देता है:
flat_schedules = (
    pd.DataFrame(tbl['schedules'].tolist())
      .stack().reset_index(level=1)
      .set_axis(['id', 'schedule_name'], axis=1)
      .drop_duplicates(ignore_index=True)
)आउटपुट:
id         schedule_name
3263524    Group 1 CORE DAYS
3263525    Group 1 CORE NIGHTS
3263526    Group 1 EDUCATION
3263527    Group 1 ROUNDING
3881368    VS Days
3881370    VS Education Shift A
3881455    VS Education Shift B
यह चरण-दर-चरण क्यों काम करता है
पहला कदम, DataFrame(tbl['schedules'].tolist()), keys को कॉलम के रूप में संरेखित करके एक wide तालिका बना देता है। इस मध्यवर्ती आउटपुट को देखने पर असर साफ दिखता है:
3263524              3263525            3263526  \
0  Group 1 CORE DAYS  Group 1 CORE NIGHTS  Group 1 EDUCATION   
1  Group 1 CORE DAYS                  NaN                NaN   
            3263527  3881368               3881370               3881455  
0  Group 1 ROUNDING      NaN                   NaN                   NaN  
1               NaN  VS Days  VS Education Shift A  VS Education Shift B  
stack() लगाने से यही wide मैट्रिक्स long index–value series में बदल जाती है, जहाँ हर पंक्ति एक अकेली key–value जोड़ी का प्रतिनिधित्व करती है—मूल सभी पंक्तियों से निकली जोड़ियाँ भी शामिल हैं:
0  3263524       Group 1 CORE DAYS
   3263525     Group 1 CORE NIGHTS
   3263526       Group 1 EDUCATION
   3263527        Group 1 ROUNDING
1  3263524       Group 1 CORE DAYS
   3881368                 VS Days
   3881370    VS Education Shift A
   3881455    VS Education Shift B
reset_index(level=1) stacked इंडेक्स से डिक्शनरी keys को एक सामान्य कॉलम में ले आता है। set_axis(['id', 'schedule_name'], axis=1) इन दो कॉलमों को नाम देता है। drop_duplicates(ignore_index=True) दोहराई गई जोड़ियों को हटाकर परिणाम को शून्य से पुनः इंडेक्स करता है।
यह बारीकी क्यों अहम है
नेस्टेड JSON लेते समय उसे शुरू में ही सुथरी और पूर्वानुमेय स्कीमा में उतार देना आगे की प्रक्रियाओं में रुकावटों से बचाता है। पिवोट से पहले पंक्तियों के पार keys को ठीक तरह से संरेखित करने से बिना बताए डेटा-हानि और joins, filters या aggregations के दौरान अजीब किनारे के मामलों से बचाव होता है। डिक्शनरी वाली कॉलम से साफ long-form तालिका में रूपांतरण करने वाला छोटा-सा पाइपलाइन समझने, जाँचने और दोबारा उपयोग करने में आसान होता है।
मुख्य बातें
दो-चरणीय reshape अपनाएँ: पहले डिक्शनरी keys को कॉलम की तरह संरेखित करके डेटा को wide बनाइए, फिर stack के साथ long जाएँ ताकि हर key–value जोड़ी के लिए एक पंक्ति निकले। अंत में keys को एक कॉलम के रूप में दिखाएँ, अर्थपूर्ण कॉलम नाम दें, और दोहराव को हटा दें। यह क्रम एक भरोसेमंद id और schedule_name मैपिंग देता है, जिसे आप निश्चिंत होकर अपने pandas वर्कफ़्लो के आगे जोड़ सकते हैं।