Unsplash . पर पेड्रो गोंजालेज द्वारा फोटो
एक बार की बात है एक छात्र था जो डेटा साइंस सीखने के लिए उत्सुक था।
उसने लोगों से पूछा कि उसे क्या करना चाहिए, और उन्होंने उसे पांडा सीखने के लिए कहा। उन्होंने डेटा पाठ्यक्रमों के लिए वेब को खंगाला, और उन सभी में पांडा थे। तो छात्र ने पंडों को सीखा, और फिर उसे एकेडेमिया में नौकरी मिल गई, जहाँ हर कोई पंडों के साथ काम कर रहा था।
इसलिए उसने कई चंद्रमाओं के लिए पंडों के साथ कड़ी मेहनत की, जब तक कि वह अपनी नींद में डेटाफ्रेम को टुकड़ा नहीं कर सका। जब वह किया गया था, वह एक डेटा बूटकैंप में शामिल हो गया: देखो और देखो, वे पांडा सिखा रहे थे। जब वह समाप्त हो गया, तो बूटकैंप ने उसे - पांडा को पढ़ाने के लिए काम पर रखा।
फिर वह समय आया जब छात्र ने अपनी पहली कंपनी में प्रवेश किया। उसका मालिक चाहता था कि वह कुछ डेटा प्रोसेस करे।
"मैं पंडों का उपयोग करूंगा" छात्र ने कहा।
"नरक तुम करेंगे!" मास्टर ने कहा। "हम यहां एस-क्यू-एल का उपयोग करते हैं" उन्होंने अपनी छड़ी के प्रहार के साथ प्रत्येक अक्षर पर जोर देते हुए जवाब दिया।
"लेकिन ... लेकिन ... वर्बोसिटी ... कुरूपता ... कार्यों की कमी ... अंतहीन नेस्टिंग ... और जोड़, जोड़ भयानक हैं! ..."
"यदि आप जंगल नहीं देख सकते हैं, तो आपको पेड़ों को नहीं छूना चाहिए" गुरु ने उसके सिर पर वार करते हुए कहा।
छात्र प्रबुद्ध था।
या तो उसने सोचा; वास्तव में गुरु के प्रहार ने उसे इतनी बुरी तरह से स्तब्ध कर दिया था कि उसका निर्णय अस्थायी रूप से बिगड़ा हुआ था।
कई चाँद बाद में, एक दर्दनाक वापसी के बाद, छात्र ने SQL को समझा। तब से उसे फिर से पंडों का उपयोग करने की आवश्यकता महसूस नहीं हुई, और गुरु ने उस पर एक और प्रहार नहीं किया।
उपरोक्त कोन आत्मकथात्मक है, हालांकि मुझे यह टिप्पणी करनी चाहिए कि मेरे किसी भी पर्यवेक्षक ने मुझे कभी नहीं मारा (भले ही उन्हें होना चाहिए)।
जब से मैंने शुरुआत की है, तब से बहुत कुछ नहीं बदला है। अधिकांश डेटा बूटकैंप के पाठ्यक्रम में पांडा (जुपिटर नोटबुक के साथ) में भारी निवेश की सुविधा है, जबकि एसक्यूएल सबसे अच्छा विचार है।
उडेमी पर "डेटा साइंस" खोजें, और आप पायथन (जिसमें अनिवार्य रूप से पांडा शामिल हैं) और आर, कभी-कभी स्काला का उल्लेख करने वाले शीर्ष पाठ्यक्रम देखेंगे। उनमें से बहुत कम लोग SQL का उल्लेख करते हैं।
मुझे लगता है कि यह खराब है, मूल्य के दृष्टिकोण से और शैक्षणिक दृष्टिकोण से।
यदि आप मानक विश्लेषण कर रहे हैं, तो SQL पांडा की तुलना में बस एक बेहतर उपकरण है। यह सरल, स्पष्ट, अधिक शक्तिशाली और कुशल है। इसे समझना, साझा करना और पुन: पेश करना भी आसान है। एक कारण है कि यह दशकों से डेटा एनालिटिक्स की भाषा रही है।
यदि आप SQL की कीमत पर पंडों पर ध्यान केंद्रित कर रहे हैं, तो आप एक बेहतर, अधिक प्रभावी डेटा प्रैक्टिशनर बनने से चूक रहे हैं।
बेशक, ऐसी चीजें हैं जो पांडा बेहतर करते हैं, और मैं लेख के अंत में संक्षेप में उनका पता लगाता हूं। लेकिन कुल मिलाकर, जब शुद्ध विश्लेषिकी की बात आती है, तो SQL को हराना मुश्किल होता है।
लोग अक्सर यह नोटिस करने में विफल रहते हैं कि पांडा जटिलता, अक्षमता, मूर्खता और भ्रम के अवसरों के संदर्भ में महत्वपूर्ण उपरि का परिचय देते हैं।
मुझे संदेह है कि पंडों पर अत्यधिक जोर देने से डेटा छात्रों को नुकसान होता है। मेरे अनुभव में, एक बिंदु है जहां अधिक पांडा करने से सीखने में बाधा उत्पन्न होती है , अर्थात व्यक्ति समय के साथ और अधिक भ्रमित हो जाता है।
नए छात्र, विशेष रूप से, अजीब मुद्दों का अनुभव करते हैं जो उन्हें भ्रमित करते हैं और जिसके लिए वे अंधे याद के साथ क्षतिपूर्ति करते हैं।
वे बुरी आदतों को भी प्राप्त कर लेते हैं जिन्हें बाद में छोड़ना मुश्किल होता है, जैसे कि जब वे टेबल संचालन का उपयोग कर सकते हैं तो पंक्तियों पर लूपिंग करना; मिश्रित प्रकार के कॉलम बनाना; सीएसवी में डेटा सहेजना; जगह में डेटा को संशोधित करना; एक ही डेटाफ़्रेम की कई प्रतियों और स्लाइसों के साथ मेमोरी को बंद करना... मैं आगे बढ़ सकता था।
इसका एक हिस्सा यह है कि पायथन एक अत्यंत सहिष्णु भाषा है, जो उपयोगकर्ता पर बोझ नहीं डालता है (जैसे मिश्रित प्रकार के साथ पांडा Series
)। इसका एक हिस्सा इस तथ्य से आता है कि पांडा एक अनिवार्य दृष्टिकोण को स्वीकार करता है (हालांकि जरूरी नहीं कि प्रोत्साहित करता है)।
उदाहरण के लिए, यदि कोई छात्र दो तालिकाओं के डेटा को संयोजित करना चाहता है, तो ऐसा कुछ भी नहीं है जो उसे इस एल्गोरिथम का उपयोग करने से रोकता है:
टेबल पर table1
प्रत्येक table1
1 पंक्ति के लिए, लुकअप के लिए सभी table2
को स्कैन करें
तालिका 2 में डेटा से table2
1 में table1
अपडेट करें
हाँ, यह स्पष्ट रूप से बहुत बुरा है। लेकिन शुरुआती कोई बेहतर नहीं जानते हैं।
इसके विपरीत, एसक्यूएल का घोषणात्मक दृष्टिकोण खराब चीजें करना कठिन बनाता है।
घोषणात्मक प्रोग्रामिंग उपयोगकर्ता को उस परिणाम के संदर्भ में सोचने के लिए मजबूर करती है जिसे वे देखना चाहते हैं, बजाय इसके कि इसे कैसे बनाया जाए । इससे उन्हें लगातार मुद्दों और अजीब बगों से घिरे रहने के बजाय, अपने विश्लेषण के पीछे के तर्क पर ध्यान केंद्रित करने की आवश्यकता होती है।
एसक्यूएल छात्रों को टेबल (यानी रिलेशनल मॉडल) और कॉलम-लेवल ऑपरेशंस में सोचने के लिए भी मजबूर करता है, जो बेहद फायदेमंद होता है जब उनकी पहली प्रवृत्ति हर चीज पर लूप करना है।
अंत में, SQL सीखने से इसकी सार्वभौमिकता और सुवाह्यता के कारण निवेश पर अधिक लाभ मिलता है।
मुझे पांडा से नफरत नहीं है। यह दो साल के लिए मेरा बुनियादी विश्लेषण उपकरण था, और मैं अब भी इसे अपने निजी प्रोजेक्ट के लिए उपयोग करता हूं। लोगों को इसे सीखते हुए देखकर मुझे खुशी होती है।
लेकिन मैं बड़ी तस्वीर देखने की कोशिश कर रहा हूं। मुझे लगता है कि एसक्यूएल की कीमत पर पंडों पर अधिक जोर देने से अच्छा से ज्यादा नुकसान होता है । खासकर जब शुरुआती लोगों की बात आती है, जो पांडा MultiIndex
के बारे में सीख रहे हैं, इससे पहले कि वे एक उचित GROUP BY
कर सकें।
अगले भाग में, मैं पंडों के कुछ अजीबोगरीब पहलुओं का विश्लेषण करता हूँ और उनकी तुलना सीधे SQL से करता हूँ।
लक्ष्य, एक बार फिर, पंडों को नीचे रखना नहीं है, बल्कि उनके निपटान में उपकरणों पर पाठक के दृष्टिकोण का विस्तार करना है।
आइए तल्लीन करें।
SELECT * FROM opinionated_comparison WHERE sql > pandas
एक ही कथन में, SQL का SELECT
आपको इसकी अनुमति देता है:
अपने इच्छित कॉलम चुनें और जिस क्रम में उन्हें वापस किया जाना चाहिए।
मौजूदा कॉलम के संयोजन और परिवर्तन के आधार पर नए कॉलम बनाएं।
कॉलम का नाम बदलें।
यह उदाहरण एक को छोड़कर सभी स्तंभों का चयन करता है, फिर दो अन्य स्तंभों के रैखिक संयोजन के आधार पर एक नया स्तंभ बनाता है:
SELECT * EXCEPT (first_name), equity_comp / total_comp * 100 AS percent_equity FROM salaries
पांडा कॉलम चयन केवल कॉलम चुनने और ऑर्डर करने की अनुमति देता है। यदि आप कुछ का नाम बदलना या बदलना चाहते हैं, तो आपको कई कथनों की आवश्यकता होती है, और बहुत से लोग डेटा को जगह में बदलने की त्रुटि के लिए गिर जाते हैं (नीचे अपरिवर्तनीयता देखें)।
शुरुआती भ्रमित हो जाते हैं क्योंकि एक कॉलम का चयन करने के लिए ब्रैकेट के एक सेट की आवश्यकता होती है ( df[”first_name”]
) जबकि कई कॉलम का चयन करने के लिए ब्रैकेट के डबल सेट की आवश्यकता होती है ( df[[”first_name”, "last_name"]]
)।
मेरे पास पांडा के साथ सबसे बड़ी समस्या है डॉट नोटेशन: तथ्य यह है कि आप इस तरह के कॉलम का चयन कर सकते हैं: df.first_name
।
यह कोष्ठक और उद्धरणों का उपयोग करने की तुलना में बहुत आसान है, इसलिए लोग इसे अत्यधिक आलस्य के कारण पसंद करते हैं। कम से कम मेरे साथ तो यही हुआ: मैं अभी भी स्वचालित रूप से डॉट नोटेशन का उपयोग करता हूं, हालांकि मुझे पता है कि यह खराब है।
समस्याएँ तब प्रकट होती हैं जब आपके पास एक कॉलम होता है जिसे count
या shape
या डिफरेंस या diff
के कई मानक विशेषताओं में से कोई भी कहा जाता है (आप उन सभी को dir(df)
के साथ देख सकते हैं)।
जब आप उन्हें डॉट नोटेशन के साथ एक्सेस करने का प्रयास करते हैं, तो आपको कॉलम के बजाय एट्रीब्यूट मिलेगा और आपका कोड टूट जाएगा।
तो पांडा के पास स्तंभों का चयन करने के तीन तरीके हैं: एक एकल स्तंभ प्राप्त करने के लिए दो (जिनमें से एक खराब और अधिक आकर्षक है!) और तीसरा एकाधिक स्तंभों का चयन करने के लिए।
SQL में, विशिष्ट पंक्तियों का चयन करने के लिए, आप केवल WHERE
कथन का उपयोग करते हैं (नीचे फ़िल्टरिंग देखें)।
पंडों में पंक्तियों का चयन करना... जटिल है। यह देखने के लिए कि यह कितना जटिल है, उपयोगकर्ता की प्रारंभिक मार्गदर्शिका देखें। या सामान्य 30 मिनट के ट्यूटोरियल में तल्लीन करें।
मैं खुद को एक उदाहरण तक सीमित रखूंगा। प्रत्येक डेटाफ़्रेम में एक Index
होती है। डिफ़ॉल्ट अनुक्रमणिका पूर्णांकों का एक क्रम है: [0,1,2,3,4,5...]
।
स्वाभाविक रूप से, ज्यादातर लोग मानते हैं कि सूचकांक पंक्तियों की कार्डिनैलिटी का प्रतिनिधित्व करता है। दरअसल, संख्याएं केवल श्रेणीबद्ध लेबल हैं! वे ['x', 'z', 'a']
जैसे यादृच्छिक अक्षर भी हो सकते हैं। कोई कार्डिनैलिटी निहित नहीं है।
इसकी अनुक्रमणिका द्वारा एक पंक्ति प्राप्त करने के लिए, आप df.loc
का उपयोग करते हैं। लेकिन पंक्ति की कार्डिनैलिटी से चयन करने के लिए, आप df.iloc
का उपयोग करते हैं। डिफ़ॉल्ट अनुक्रमणिका के साथ, ये दो विधियां समान परिणाम देती हैं।
जो केवल भ्रम में जोड़ता है, क्योंकि किसी भी बिंदु पर आपका सूचकांक पूरी तरह से यादृच्छिक रूप से बदल सकता है जैसे [7, 2, 2, 'c', True, None]
। हाँ, यह सब अनुमति है! और इसे रोकने के लिए कोई बाधा नहीं है (नीचे प्रतिबंध देखें)।
कल्पना कीजिए कि आपने अपना कोड यह मानकर लिखा है कि सूचकांक पंक्ति कार्डिनैलिटी का प्रतिनिधित्व करता है। अब:
df.loc[7]
पहली पंक्ति लौटाएगाdf.loc[2]
एक पंक्ति के बजाय एक डेटाफ़्रेम स्लाइस लौटाएगा (क्योंकि यह अनुक्रमणिका में एक से अधिक बार होता है)df.loc[None]
एक वास्तविक पंक्ति लौटाएगा!
मैं रो नहीं रहा तुम रो रहे हो।
और हाँ: एक ही विधि एक अदिश मान, एक पंक्ति या एक डेटाफ़्रेम स्लाइस लौटा सकती है जो इस बात पर निर्भर करता है कि सूचकांक कैसे बना है। पांडा डॉक्स इस पागलपन को स्वीकार करते हैं:
अनुक्रमण जैसी अन्य विधियां बहुत ही आश्चर्यजनक परिणाम दे सकती हैं। आमतौर पर एक अदिश के साथ अनुक्रमणित करने से आयामीता कम हो जाएगी।
DataFrame
को स्केलर के साथ काटने से एकSeries
वापस आ जाएगी। एक स्केलर के साथ एकSeries
को टुकड़ा करना एक स्केलर लौटाएगा। लेकिन [इंडेक्स] डुप्लीकेट के साथ, ऐसा नहीं है।
और याद रखें, इंडेक्स को डुप्लीकेट रखने से रोकने के लिए कोई बाधा नहीं है। मैं आपको यह बताना शुरू नहीं कर सकता कि इससे मुझे कितने सिरदर्द हुए हैं।
(हमारे द्वारा बताए गए चयन के सभी तरीकों के अलावा, पांडा में एकल मानों के लिए df.at
और df.iat
भी हैं। याद रखने वाली और भ्रमित करने से बचने के लिए एक और बात है।)
SQL में, फ़िल्टर करना सीधा है। WHERE
लिखें, जितने चाहें उतने स्टेटमेंट डालें, और उन्हें लॉजिकल ऑपरेटर्स के साथ एक साथ चेन करें। ब्रैकेट आपको स्ट्रक्चरिंग एक्सप्रेशन पर अधिक नियंत्रण देते हैं।
उदाहरण के लिए, निम्नलिखित क्वेरी उन लोगों के लिए फ़िल्टर करती है जो दोनों 30 से अधिक हैं और दो शर्तों में से कम से कम एक को पूरा करते हैं: 5 वर्ष से अधिक कार्यकाल या 50 से कम इक्विटी मुआवजा:
SELECT * from salaries WHERE age > 30 AND (tenure > 5 OR equity_comp < 50)
यह पंडों में कैसा दिखता है?
new_df = df[(df["age"] > 30) & ((df["tenure"] > 5) | (df["equity_comp"] < 50))]
उह। शुरुआती लोगों को यह समझाने में मज़ा लें।
माना, आप शायद इसे इस तरह नहीं लिखेंगे क्योंकि यह बहुत बदसूरत है। आप कई कथनों में फ़िल्टरिंग निष्पादित करेंगे: जिसका अर्थ है कोड की अधिक पंक्तियाँ, चर और दोहराव।
पांडा फ़िल्टर बूलियन इंडेक्सिंग नामक विधि पर आधारित होते हैं। प्रत्येक फ़िल्टरिंग ऑपरेशन दो चरणों में होता है:
आप एक Series
लेते हैं (वह कॉलम ऑब्जेक्ट है) और प्रत्येक तत्व को बूलियन टेस्ट के माध्यम से चलाएं। इस प्रकार इसे बूलियन मूल्यों (सत्य या गलत) से बनी एक नई Series
में बदलना।
आप इस कॉलम के साथ डेटाफ्रेम का चयन करते हैं, जो उन पंक्तियों को छोड़कर समाप्त होता है जहां बूलियन Series
में गलत मान होता है।
यहाँ छिपी धारणा पर ध्यान दें? फ़िल्टर करने के लिए उपयोग की जाने वाली Series
और फ़िल्टर किए जा रहे डेटाफ़्रेम को समान अनुक्रमणिका, समान क्रम में साझा करने की आवश्यकता होती है। यह हमेशा गारंटी नहीं है।
व्यवहार में, बूलियन अनुक्रमण का अर्थ है कि जब आप फ़िल्टर करते हैं, तो आपको हमेशा डेटाफ़्रेम चर दोहराना होता है, जैसे salaries[salaries["cash_comp"] > 20]
। जब आप बहुत सारे कोड लिख रहे हों तो यह बहुत कष्टप्रद होता है! ऊपर दिया गया उदाहरण देखें: डेटाफ़्रेम वैरिएबल को 4 बार संदर्भित किया गया है।
मैं अनुभव से यह भी कह सकता हूं कि शुरुआती लोगों के लिए बूलियन इंडेक्सिंग को समझना आसान नहीं है। कुछ लोगों को अंतर्निहित तंत्र कभी नहीं मिलता है। वे सिर्फ कोडिंग पैटर्न को याद करते हैं।
( df.query()
विधि फ़िल्टरिंग के लिए एक बेहतर विधि प्रदान करती प्रतीत होती है।)
यहां कोई बड़ी शिकायत नहीं है। लेकिन एसक्यूएल निश्चित रूप से अंग्रेजी के करीब है। ये दोनों समकक्ष हैं:
SELECT AVG(cash_comp), SUM(tenure) FROM salaries GROUP BY department
grouped_df = df.groupby('department').agg({"cash_comp": np.mean, "tenure": np.sum})
SQL में एक प्रकार का जुड़ाव होता है। इसे JOIN
कहते हैं। ज़रूर, यह बाएँ/दाएँ और भीतरी/बाहरी हो सकता है, लेकिन उपयोग बहुत सीधा है।
पंडों की दो विधियाँ हैं: join
और merge
। मुझे कभी समझ नहीं आया कि हमें दो की आवश्यकता क्यों है। join
इंडेक्स पर काम करना चाहिए, merge
किसी भी कॉलम पर काम करना चाहिए।
लेकिन अगर आप डॉक्स [ 1 ] [ 2 ] को देखते हैं तो वे प्रत्येक इंडेक्स और कॉलम दोनों का समर्थन करते प्रतीत होते हैं। मैं भ्रम हूँ। (यदि आप संदेह में हैं, तो मेरा सुझाव है कि हमेशा merge
का चयन करें क्योंकि join
एक विरासत पद्धति है।)
SQL तार्किक स्थितियों की एक श्रृंखला के आधार पर जॉइन करना वास्तव में आसान बनाता है, जैसे: भूमिका से जुड़ें, लेकिन केवल तभी जब लंदन का वेतन वाशिंगटन के वेतन से अधिक हो, या व्यक्ति का कार्यकाल लंबा हो।
SELECT * FROM london_hq lhq JOIN washington_hq whq ON lhq.role = whq.role AND (lhq.salary > whq.salary OR lhq.tenure > whq.tenure)
जहाँ तक मुझे पता है, यह पांडा के साथ संभव नहीं है। शामिल होने (या विलय) करते समय आप केवल समानता की स्थिति का उपयोग कर सकते हैं।
तो आपको पहले जॉइन ऑन role
निष्पादित करना होगा, प्रत्येक कॉलम की उत्पत्ति का ट्रैक रखना होगा और फिर परिणाम पर फ़िल्टर करना होगा।
हालांकि, मैं तर्क दूंगा कि वे शर्तें जॉइन में सही हैं और समानता तुलना का उपयोग न करने के लिए कम प्रासंगिक नहीं हैं।
एसक्यूएल के प्रमुख लाभों में से एक यह है कि प्रत्येक कॉलम में एक अच्छी तरह से परिभाषित प्रकार होता है। इसके अलावा, कॉलम में मिश्रित प्रकार की अनुमति नहीं है। यह लंबे समय में बहुत सारे कीड़े और सिरदर्द से बचाता है।
जब आप पांडा में डेटा लोड करते हैं, तो अधिकांश कॉलम स्वचालित रूप से object
के रूप में टाइप हो जाते हैं। इसका मतलब तीन चीजों में से एक हो सकता है:
स्तंभ में केवल तार हैं
कॉलम में पायथन ऑब्जेक्ट हैं जो एक आदिम डेटा प्रकार नहीं हैं, जैसे सूची या शब्दकोश
कॉलम में मिश्रित प्रकार हैं
जब आप object
डेटा प्रकार देखते हैं, तो आप कभी नहीं जानते कि मामला क्या है। मुझे यह बहुत कष्टप्रद लगता है।
एसक्यूएल के विपरीत, आप पांडा में मिश्रित प्रकार के साथ डेटा लोड कर सकते हैं: उन्हें बस object
के रूप में टाइप किया जाएगा।
पांडा आपको एक स्कीमा निर्दिष्ट करने और उसके साथ रहने के लिए बाध्य नहीं करता है। जब आप शुरुआत कर रहे होते हैं तो यह आपको एक गति प्रीमियम देता है, लेकिन आप अक्सर भविष्य में बग और भ्रम में इसके लिए महंगा भुगतान करते हैं।
यह उन शुरुआती लोगों के लिए विशेष रूप से समस्याग्रस्त है जो आम नुकसान के प्रति सतर्क नहीं हैं। उदाहरण के लिए, जब मैं पंडों के साथ काम कर रहा था, तो मैं अक्सर डेटाटाइम ऑपरेशन का प्रयास करता था, केवल यह महसूस करने के लिए कि डेटाटाइम कॉलम स्ट्रिंग्स से बना था (इसलिए object
के रूप में वर्गीकृत)। मैं भोलेपन से ऐसा करूँगा:
df['Date'] = df['Date'].astype('datetime64[ns]')
और आगे बढ़ें, केवल बहुत बाद में यह पता लगाने के लिए कि पंडों के डेट पार्सर ने मेरे स्ट्रिंग्स को गलत तरीके से पढ़ा था और तारीखों का कोई मतलब नहीं था।
आइए ईमानदार रहें: अधिकांश लोग अपने डेटाफ्रेम को सीएसवी के रूप में संग्रहीत करते हैं। पंडों के छात्रों का स्वागत है, ऐसा करने के लिए प्रोत्साहित नहीं किया जाता है। यह विचार अच्छा नहीं है!
ज़रूर, सीएसवी मानव पठनीय हैं और ... उनके फायदे यहीं समाप्त होते हैं। उनके नुकसान हैं:
CSV में कनवर्ट करते समय, आप स्कीमा और कॉलम प्रकारों की सभी जानकारी खो देते हैं। सब कुछ पाठ में वापस आ जाता है।
सीएसवी खराब स्वरूपण, भ्रष्टाचार और पार्सिंग त्रुटियों से ग्रस्त हैं।
CSV को संपीड़ित करना कठिन होता है, जिससे संग्रहण लागत बढ़ जाती है.
सीएसवी प्रारूप अनिर्दिष्ट है , जिसका अर्थ है कि विभिन्न कार्यक्रम अलग-अलग तरीकों से सीएसवी बनाते हैं, और बोझ उपयोगकर्ता के साथ यह पता लगाने के लिए है कि उन्हें कैसे पार्स किया जाए। यह जल्दी से एक नारकीय अनुभव में बदल सकता है, जैसा कि कोई भी डेटा पेशेवर प्रमाणित करेगा।
पांडा में काम करने वाले लोगों के लिए स्कीमा का नुकसान आम तौर पर सबसे बड़ा मुद्दा है। यह एक सामान्य स्थिति है:
आपका काम CSV से शुरू होता है। बशर्ते आपने पांडा के read_csv
के लिए सही स्वरूपण, एन्कोडिंग, उद्धरण चार विनिर्देश और बाकी कई तर्कों का पता लगा लिया हो, तो आप इसे डेटाफ़्रेम में लोड करेंगे। अब आपको कॉलम की खोज में समय बिताने की जरूरत है, प्रत्येक कॉलम को सही प्रकार में कास्टिंग करना, प्रक्रिया में दिखाई देने वाले किसी भी बग का ख्याल रखना और यह सत्यापित करना कि अंतिम परिणाम समझ में आता है। (या आप तुरंत काम करना शुरू कर सकते हैं और बाद में बहुत सारी बग का सामना कर सकते हैं)।
एक बार आपका काम हो जाने के बाद, आपके पास एक नया डेटाफ़्रेम होगा। आप इससे क्या करने वाले हैं? क्यों, इसे CSV के रूप में सहेजें। अब स्कीमा परिभाषा पर आपके सभी पिछले कार्य समाप्त हो गए हैं, क्योंकि डेटाफ़्रेम टेक्स्ट में डंप कर दिया गया है।
आपको किसी अन्य कार्यप्रवाह के लिए नया डेटाफ़्रेम लोड करने की आवश्यकता है। इसका मतलब है कि आपने अभी जो सीएसवी डंप किया है उसे लोड करना। मुझे आशा है कि आपने ऐसे कार्य लिखे हैं जो स्कीमा को सफलतापूर्वक पुनर्स्थापित कर सकते हैं, या आपको काम फिर से करना होगा (बशर्ते आपको याद हो कि प्रत्येक कॉलम को क्या करना था)।
CSV को किसी मित्र के साथ साझा करना चाहते हैं या इसे GitHub पर पोस्ट करना चाहते हैं? आप उस कोड को बेहतर ढंग से साझा करते हैं जो स्कीमा को फिर से लागू कर सकता है, और आशा करता है कि वे इसे चलाने के इच्छुक और सक्षम हैं। या उनके पास टेक्स्ट की एक बूँद रह जाएगी और उन्हें शुरू से ही सभी स्कीमा इंप्यूटेशन कार्य को दोहराना होगा।
बेतुका लगता है? मैंने इसे अनगिनत बार करते देखा है। यह मैंने खुद किया है! लेकिन अब मुझे आश्चर्य है: हम लोगों को इस तरह काम करना क्यों सिखाते हैं? इस तरह के पागलपन और क्रूरता का क्या औचित्य है?
यहां दो समाधान हैं।
यदि आपको वास्तव में पांडा में काम करने की ज़रूरत है, तो अपने डेटाफ्रेम को लकड़ी की छत में निर्यात करें।
या आप SQL में काम कर सकते हैं और अपने आप को सारी परेशानी से बचा सकते हैं। आखिरकार, डेटा स्टोर करने के लिए डेटाबेस सबसे अच्छी जगह है।
अपने आप से पूछें: मुझे फ़ाइल परत की आवश्यकता क्यों है? यदि आप बस कुछ डेटा पढ़ रहे हैं, इसे संसाधित कर रहे हैं और फिर परिणाम संग्रहीत कर रहे हैं, तो शायद आप नहीं करते हैं। डेटाबेस से लोड करें, डेटाबेस में काम करें, डेटाबेस में सहेजें। यह इत्ना आसान है। बाहरी रूप से डेटा साझा करने की आवश्यकता है? लकड़ी की छत में निर्यात करें।
दुनिया को और सीएसवी की जरूरत नहीं है।
नोट: कुछ लोग अपने डेटाफ़्रेम को चुनकर स्कीमा समस्या को हल करने का प्रयास करते हैं। यह एक भयानक विचार है ।
अचार बनाना अक्षम और असुरक्षित है (ऐसा अचार कभी न खोलें जिस पर आपको भरोसा न हो!) एक मसालेदार डेटाफ्रेम केवल पायथन के अंदर खोला जा सकता है, और इसे उसी पुस्तकालय वातावरण में होना चाहिए (जिसके बारे में उपयोगकर्ता बिल्कुल कुछ भी नहीं जानता)। यदि पंडों ने अचार को पढ़ने वाले पंडों को लिखने वाले पंडों की तुलना में एक अलग संस्करण है, तो फ़ाइल अपठनीय हो सकती है!
लापता डेटा को इंगित करने के लिए SQL NULL मानों का उपयोग करता है। आप आसानी से नल को फ़िल्टर कर सकते हैं।
SELECT * FROM salaries WHERE equity_comp IS NOT NULL AND cash_comp IS NOT NULL
पंडों में, लापता मान इनमें से कोई भी हो सकता है:
पायथन का मूल None
(जो पंडों को None
के रूप में प्रदर्शित करता है लेकिन nan
जैसा व्यवहार करता है)
numpy.nan
pandas.NA
pandas.NaT
(डेटाटाइम्स के लिए)
आइए numpy.nan
पर ध्यान दें जो सबसे आम है:
इस ऑब्जेक्ट का प्रकार float
है, इसलिए टाइप चेक के साथ इसका पता लगाना भूल जाएं।
यह सच है, इसलिए बूलियन परीक्षणों के बारे में भूल जाओ। bool(np.nan)
True
है।
यह समानता परीक्षण में विफल रहता है, क्योंकि numpy.nan == numpy.nan
गलत है। nan
खुद के बराबर नहीं है!
किसी ऑपरेशन में nan
का उपयोग करने से कोई अपवाद नहीं होता है, इसका सीधा सा मतलब है कि परिणाम nan
है।
क्या यह मजेदार नहीं है?
एक nan
का पता लगाने का एकमात्र तरीका pandas.isna()
का उपयोग करना है। यह ठीक है, एक बार जब आप दस्तावेज़ पढ़ लेते हैं और अपनी सभी पाइथोनिक प्रवृत्ति को भूल जाते हैं। फिर भी, यह व्यवहार शुरुआती लोगों के लिए बेहद भ्रमित करने वाला है।
यहां बताया गया है कि आप पंडों में उपरोक्त क्वेरी को कैसे दोहरा सकते हैं:
new_df = df.dropna(subset=["equity_comp", "cash_comp"])
एसक्यूएल में बाधाएं महत्वपूर्ण हैं। वे आपको ऐसे नियम निर्दिष्ट करने की अनुमति देते हैं जो आपके डेटा को सुरक्षित और सुसंगत रखते हैं। उदाहरण के लिए, प्राथमिक कुंजी, जो प्रत्येक पंक्ति के लिए विशिष्ट पहचानकर्ता के रूप में कार्य करती है, अद्वितीय होनी चाहिए और शून्य नहीं होनी चाहिए।
पंडों के पास ऐसा कुछ नहीं है।
पांडा में प्राथमिक कुंजी की सबसे नज़दीकी चीज अनुक्रमणिका है। दुर्भाग्य से सूचकांक मूल्य दोहराया और अशक्त दोनों हो सकता है (हाँ, आपके पास None
हो सकता है)।
उपयोगकर्ता अक्सर इस निहित धारणा के साथ काम करते हैं कि सूचकांक एक प्राथमिक कुंजी है, इस तथ्य से लागू एक विचार है कि डिफ़ॉल्ट सूचकांक पूर्णांक से बना है: [0,1,2,3,4...]
। इसलिए लोग विशिष्ट पंक्तियों को संदर्भित करने के लिए अनुक्रमणिका का उपयोग करते हैं, जैसे df.loc[2]
।
'यह विश्वास का एक मूर्खतापूर्ण कार्य है। विभिन्न डेटाफ़्रेम को संयोजित या मर्ज करते समय यह स्पष्ट हो जाता है। अक्सर ऐसा होता है कि समान इंडेक्स मिश्रित होते हैं और आपको ऐसा इंडेक्स मिलता है जो इस तरह दिखता है: [0,1,2,2,2,3...]
।
पंडों ने इसके बारे में कोई चेतावनी नहीं दी है, इसलिए आपको पहले इसका एहसास नहीं होता है। लेकिन अगली बार जब आप df.loc[2]
का उपयोग करेंगे तो आपका कोड टूट जाएगा क्योंकि एक पंक्ति के बजाय अब यह तीन पंक्तियों के साथ एक डेटाफ़्रेम लौटाएगा।
इससे पहले कि आप यह समझें कि आपको मर्ज किए गए डेटाफ़्रेम पर reset_index()
चलाने की आवश्यकता है, इससे पहले कई आँसू बहेंगे ताकि प्रत्येक पंक्ति को फिर से एक अद्वितीय मूल्य मिल सके।
इसके अलावा, SQL बाधाएं आपको लेखन समय पर चेक चलाने की अनुमति देती हैं। यदि आप एक कॉलम में एक शून्य मान डालने का प्रयास करते हैं जिसमें NOT NULL
, तो आपको अपवाद मिलता है और खराब लेखन नहीं होता है। पांडा केवल पढ़ने पर चेक चलाने की अनुमति देता है। यानी अगर आप इसे करना याद रखें।
यह मुख्य रूप से एक शैक्षणिक बिंदु है। पंडों, जैसा कि सर्वविदित है, वेक्टरकृत संचालन की अनुमति देता है और यहां तक कि प्रोत्साहित करता है (जहां एक श्रृंखला के सभी तत्वों को समानांतर में एक्सेस किया जाता है)।
लेकिन पाइथन में काम करने वाले बहुत से लोग अपने आप ऐसा नहीं सोचते हैं। उन्होंने लूप सीखकर शुरुआत की और अब, गुइडो द्वारा , वे उन लूपों का उपयोग करना चाहते हैं।
जब वे पांडा के साथ शुरुआत करते हैं, तो वे जल्द ही पुनरावृत्त और itertuples
iterrows
लूप करने की अनुमति देते हैं।
लगभग अनिवार्य रूप से, वे फिर से लूपिंग पैटर्न में पड़ जाते हैं, क्योंकि कुछ भी उन्हें वैक्टर में सोचने के लिए मजबूर नहीं करता है। यह उन्हें भयानक कोड लिखने का कारण बनता है जो बहुत धीमी गति से चलता है।
मैंने पांडा के साथ लंबे अनुभव के बाद एसक्यूएल पर ध्यान देना शुरू किया। हर बार जब मुझे SQL समस्या का सामना करना पड़ा, तो मेरी प्रवृत्ति एक लूप समाधान के साथ आने की थी। निराशाजनक रूप से, SQL ने मुझे ऐसा करने की अनुमति नहीं दी।
इसके घोषणात्मक वाक्य-विन्यास ने मुझे स्तंभ संचालन, जॉइन और विंडो कार्यों के संदर्भ में सोचने के लिए मजबूर किया। धीरे-धीरे, मैंने मानसिक मॉडल का एक नया सेट बनाया जिसने मुझे एक बेहतर विश्लेषक बना दिया।
मुझे लगता है कि शिक्षार्थियों को पांडा के साथ शुरू करने से पहले एसक्यूएल में डेटा में हेरफेर करने वाले आत्मविश्वास का निर्माण करना चाहिए। वे समझने के लिए बेहतर ढंग से सुसज्जित होंगे जब पंक्ति द्वारा लूपिंग अपरिहार्य है, जो दुर्लभ है।
आप स्मृति में डेटाफ़्रेम लोड करते हैं। आपको उस डेटाफ्रेम को संशोधित करने की आवश्यकता है। क्या आप इसे अपने स्थान पर बदलते हैं, या आप इसकी एक प्रति बनाते हैं? क्या आपको मौजूदा कॉलम अपडेट करने चाहिए या नए कॉलम बनाने चाहिए?
क्या होगा यदि आपको कई डेटाफ़्रेम स्लाइस बनाने की आवश्यकता है, तो प्रत्येक स्लाइस पर कुछ काम करें? क्या आपको प्रत्येक स्लाइस को एक अलग वेरिएबल में स्टोर करना चाहिए या अलग-अलग स्लाइस को बारी-बारी से रखने के लिए एक ही वेरिएबल का उपयोग करना चाहिए?
जब लोग पंडों में काम करते हैं, तो वे इन सभी कामों को एक ही समय में करते हैं। जल्द ही उन सभी चरों पर नज़र रखना मुश्किल हो जाता है जिनमें डेटाफ़्रेम, डेटाफ़्रेम के स्लाइस और स्लाइस के स्लाइस होते हैं, और यह जानना मुश्किल हो जाता है कि डेटा कैसे जोड़ा या संशोधित किया गया था।
(मैं हमेशा पांडा नहीं लिखता, लेकिन जब मैं करता हूं, तो मुझे प्रतिलिपि चेतावनी के साथ सेटिंग मिलती है।)
और चूंकि अधिकांश लोग नोटबुक के साथ पांडा का उपयोग करते हैं, ये समस्याएं सामान्य नोटबुक नुकसान के साथ मिश्रित होती हैं और अंत में भारी सिरदर्द पैदा करती हैं।
यह एक कारण है कि मुझे लगता है कि पांडा डेटा विश्लेषण के लिए सबसे अच्छा विकल्प नहीं है।
SQL में डेटा संसाधित करते समय, आप मूल डेटा नहीं बदलते हैं। विश्लेषण में UPDATE
विवरण का उपयोग नहीं किया जाता है। इसके बजाय, आप तालिकाओं और दृश्यों की पाइपलाइन बनाते हैं जो विभिन्न चयनों का प्रतिनिधित्व करते हैं।
जब आपको अपने परिणामों को सहेजने की आवश्यकता होती है, तो आप नई तालिकाएँ बनाते हैं (या मौजूदा लक्ष्य तालिकाओं में पंक्तियाँ जोड़ते हैं, लेकिन पिछली पंक्तियों को संशोधित या हटाए बिना)। यह अपरिवर्तनीयता के सिद्धांत का सम्मान करता है: स्रोत डेटा को कभी भी संशोधित या हटाएं नहीं। यह आपकी प्रक्रिया को सुरक्षित, पारदर्शी और दोहराने में आसान बनाता है।
हां, आप पंडों में अपरिवर्तनीयता का सम्मान कर सकते हैं, लेकिन यह स्पष्ट नहीं है कि आपको ऐसा करना चाहिए, और बहुत से लोग इसे करना कभी नहीं सीखते हैं। आप आमतौर पर फाइलों के स्तर पर अपरिवर्तनीयता देखते हैं: लोग आमतौर पर एक सीएसवी लोड करते हैं और एक नया सीएसवी आउटपुट करते हैं। लेकिन उस काम के लिए जो बीच में होता है? कुछ भी हो जाता।
(अधिकांश पांडा विधियां सैद्धांतिक रूप से "शुद्ध" हैं क्योंकि वे पिछले एक को संशोधित करने के बजाय एक नया डेटाफ़्रेम लौटाते हैं। लेकिन वे सभी inplace
विकल्प प्रदान करते हैं जो एक डेटाफ़्रेम को जगह में बदल देता है। और लोग इसे उत्साह के साथ उपयोग करते हैं।)
यदि आप पंडों के साथ गंभीर काम करते हैं, तो आप अंततः एक प्रदर्शन दीवार से टकराएंगे। आप जिस डेटा का विश्लेषण कर रहे हैं वह अभी बहुत बड़ा है, या आपकी संसाधन आवश्यकताएँ बहुत अधिक हैं।
मैंने इसे अक्सर देखा जब मैं पंडों के साथ शोध कर रहा था। जब ऐसा हुआ, तो मैं और मेरे सहयोगियों ने "पंडों को तेज़ बना दिया" और इस गर्म विषय पर अनगिनत लेख खोजे, जिन्होंने बदले में अनगिनत हैक्स, ऑप्टिमाइज़ेशन और पीईपीआई पुस्तकालयों का प्रस्ताव दिया, जिन्होंने चाल करने का वादा किया था।
यदि आप इस स्थिति में हैं, तो हर तरह से उपलब्ध संसाधनों की जाँच करें। विशेष रूप से वे जो बताते हैं किपांडा का बेहतर उपयोग कैसे करें। लेकिन अपनी उम्मीदों को ज्यादा मत बढ़ाइए। पांडा क्या कर सकते हैं, इसकी कठिन सीमाएँ हैं। यह ठीक है: यह सभी डेटा एनालिटिक्स के अंत के लिए डिज़ाइन नहीं किया गया था।
जब आपको अपने डेटा वर्कलोड को स्केल करने की आवश्यकता हो तो दो सबसे अच्छे विकल्प हैं:
पायस्पार्क । स्पार्क बड़े पैमाने पर विश्लेषण और समानांतर डेटा प्रोसेसिंग के लिए एक इंजन है। PySpark आपको Python के साथ इसका लाभ उठाने की अनुमति देता है, और एक सिंटैक्स का उपयोग करता है जो पांडा की याद दिलाता है। इसमें पांडा एपीआई भी है।
डेटा गोदाम । बहुत बड़े पैमाने पर डेटा के भंडारण और विश्लेषण के लिए एक प्रणाली (टेराबाइट्स और पेटाबाइट्स सोचें)। आधुनिक डेटा वेयरहाउस क्लाउड में चलते हैं ताकि आप किसी सर्वर को प्रबंधित किए बिना वितरित सिस्टम की शक्ति का लाभ उठा सकें। BigQuery, Google क्लाउड का डेटा वेयरहाउस समाधान, 30 सेकंड में 100 बिलियन पंक्तियों या 7 टेराबाइट डेटा को संसाधित कर सकता है । डेटा वेयरहाउस आमतौर पर SQL के साथ काम करते हैं। (यदि आप BigQuery को निःशुल्क आज़माना चाहते हैं, तो मैंने इसके बारे में यहाँ लिखा है। )
मैं नहीं चाहता कि आप पांडा से दूर रहें। यह एक अद्भुत उपकरण है जो निश्चित रूप से सीखने लायक है।
ऐसे मामले हैं जहां पांडा SQL से बेहतर विकल्प है। मैं यहाँ विस्तार में नहीं जाऊँगा, लेकिन यहाँ एक त्वरित सूची है:
अन्य पायथन वर्कफ़्लोज़ के साथ एकीकृत करते समय, उदाहरण के लिए आप मशीन लर्निंग कर रहे हैं या आप पायथन विज़ुअलाइज़ेशन लाइब्रेरी का उपयोग करना चाहते हैं।
जब आपको कुछ त्वरित आँकड़ों की आवश्यकता होती है। describe()
विधि बहुत उपयोगी है।
जब आपको पैमाने या पुनरुत्पादन के बारे में चिंता किए बिना, एक त्वरित विश्लेषण को एक साथ थप्पड़ मारने की आवश्यकता होती है। हालाँकि एक्सेल या गूगल शीट्स भी काम कर सकते हैं।
यदि आप पायथन एप्लिकेशन बना रहे हैं। पंडों एक मनमानी डेटा संरचना से तालिका में जाने का सबसे तेज़ तरीका हो सकता है, और इसके विपरीत।
जब आपको वास्तव में अनिवार्य वर्कफ़्लो और लूप की आवश्यकता होती है। जैसे मार्कोव सिमुलेशन का निर्माण।
जब आपको असामान्य कार्यों को लिखने या पुन: उपयोग करने की आवश्यकता होती है। पांडस मनमाने ढंग से पायथन कार्यों को लागू करने में महान हैं।
यदि आपके पास अत्यधिक गतिशील और पैरामीट्रिज्ड वर्कफ़्लो है।
मुझे उम्मीद है कि इस लेख ने आपको SQL और पांडा और उनकी सापेक्ष शक्तियों और कमजोरियों के बारे में अधिक गहराई से सोचने के लिए प्रेरित किया है।
मेरा मानना है कि डेटा में मौजूदा रुझान पांडा के पक्ष में बहुत आगे बढ़ गया है, और आप अपने जोखिम पर एसक्यूएल को अनदेखा करते हैं।
यहाँ मेरी सलाह है:
यदि आप एक शिक्षार्थी हैं : SQL का अध्ययन करें और अपने विश्लेषण के लिए इसका उपयोग करना सीखें। आपको इसका पछतावा नहीं होगा।
यदि आप एक पाठ्यक्रम डिजाइनर हैं : अपने छात्रों को SQL में तब तक डुबोएं जब तक कि वे टेबल में सपने न देखें और सभी कैप्स में बोलें। यह कठिन प्यार है और वे इसके लिए आपसे नफरत करेंगे, लेकिन वे कब समझेंगे। (हालांकि उन्हें सिर पर मत मारो।)
यदि आप एक संरक्षक हैं : धीरे-धीरे अपने विद्यार्थियों को पंडों से दूर करने का प्रयास करें और उन्हें SQL में समस्याओं का प्रयास करने के लिए प्रोत्साहित करें।
मुझे बातचीत जारी रखना अच्छा लगेगा। बेझिझक एक टिप्पणी छोड़ें, मुझे एक ईमेल लिखें या मुझे लिंक्डइन पर जोड़ें।