एक DataFrame बनाने का सही तरीका ™ है
TLDR; (सिर्फ बोल्ड टेक्स्ट पढ़ें)
यहां अधिकांश उत्तर आपको बताएंगे कि खाली डेटाफ़्रेम कैसे बनाएं और इसे कैसे भरें, लेकिन कोई भी आपको नहीं बताएगा कि यह करना गलत है।
यहाँ मेरी सलाह है: जब तक आप सुनिश्चित करें कि आपके पास काम करने के लिए आवश्यक सभी डेटा हैं, तब तक प्रतीक्षा करें। अपना डेटा एकत्र करने के लिए एक सूची का उपयोग करें, फिर जब आप तैयार हों तो एक DataFrame को इनिशियलाइज़ करें।
data = []
for a, b, c in some_function_that_yields_data():
data.append([a, b, c])
df = pd.DataFrame(data, columns=['A', 'B', 'C'])
यह हमेशा एक सूची में संलग्न करने के लिए और एक बार में एक से एक DataFrame बनाने की तुलना में सस्ता है , यह एक खाली DataFrame (या NaNs में से एक) बनाने के लिए और बार-बार इसे करने के लिए अपील है। सूचियाँ भी कम मेमोरी लेती हैं और साथ काम करने , जोड़ने और हटाने (यदि आवश्यक हो) के लिए एक बहुत हल्का डेटा संरचना हैं ।
इस पद्धति का अन्य लाभ dtypes
स्वचालित रूप से अनुमानित हैं ( object
उन सभी को निर्दिष्ट करने के बजाय )।
पिछले लाभ यह है कि है एक RangeIndex
स्वचालित रूप से आपके डेटा के लिए बनाया जाता है, तो यह के बारे में चिंता करने के लिए एक कम बात (गरीब पर एक नज़र है, append
और loc
नीचे दिए गए तरीकों, आप दोनों कि उचित रूप से सूचकांक से निपटने की आवश्यकता होती है में तत्वों देखेंगे)।
चीजें जो आपको नहीं करनी चाहिए
append
या concat
एक लूप के अंदर
यहाँ सबसे बड़ी गलती है जो मैंने शुरुआती लोगों से देखी है:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df = df.append({'A': i, 'B': b, 'C': c}, ignore_index=True) # yuck
# or similarly,
# df = pd.concat([df, pd.Series({'A': i, 'B': b, 'C': c})], ignore_index=True)
आपके द्वारा किए गए प्रत्येक append
या concat
ऑपरेशन के लिए मेमोरी फिर से आवंटित की जाती है। इसे एक लूप के साथ युगल करें और आपके पास एक द्विघात जटिलता ऑपरेशन है । से df.append
डॉक पेज :
किसी डेटाफ़्रेम में समान रूप से जोड़ देने वाली पंक्तियाँ एकल संगति से अधिक कम्प्यूटेशनल रूप से गहन हो सकती हैं। एक बेहतर उपाय यह है कि उन पंक्तियों को एक सूची में जोड़ दिया जाए और फिर सूची को मूल DataFrame के साथ एक ही बार में पूरा किया जाए।
इससे जुड़ी दूसरी गलती df.append
यह है कि उपयोगकर्ता भूल जाते हैं कि एपेंड एक इन-प्लेस फ़ंक्शन नहीं है , इसलिए परिणाम को वापस सौंपा जाना चाहिए। तुम भी dtypes के बारे में चिंता करने की ज़रूरत है:
df = pd.DataFrame(columns=['A', 'B', 'C'])
df = df.append({'A': 1, 'B': 12.3, 'C': 'xyz'}, ignore_index=True)
df.dtypes
A object # yuck!
B float64
C object
dtype: object
ऑब्जेक्ट कॉलम से निपटना कभी भी अच्छी बात नहीं है, क्योंकि पांडा उन कॉलमों पर परिचालन को वेक्टर नहीं कर सकते हैं। इसे ठीक करने के लिए आपको यह करने की आवश्यकता होगी:
df.infer_objects().dtypes
A int64
B float64
C object
dtype: object
loc
एक लूप के अंदर
मैंने loc
एक DataFrame को खाली करने के लिए उपयोग करने के लिए भी देखा है जो खाली बनाया गया था:
df = pd.DataFrame(columns=['A', 'B', 'C'])
for a, b, c in some_function_that_yields_data():
df.loc[len(df)] = [a, b, c]
पहले की तरह, आपको प्रत्येक बार आवश्यक मेमोरी की मात्रा पूर्व-आबंटित नहीं की गई है, इसलिए हर बार जब आप एक नई पंक्ति बनाते हैं , तो मेमोरी फिर से बढ़ जाती है । यह उतना ही बुरा है append
, और इससे भी ज्यादा बदसूरत।
NaNs का खाली डेटाफ़्रेम
और फिर, NaNs का एक DataFrame बना रहा है, और इसके साथ सभी कैविएट जुड़े हुए हैं।
df = pd.DataFrame(columns=['A', 'B', 'C'], index=range(5))
df
A B C
0 NaN NaN NaN
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
4 NaN NaN NaN
यह अन्य की तरह ऑब्जेक्ट कॉलम का एक डेटाफ़्रेम बनाता है।
df.dtypes
A object # you DON'T want this
B object
C object
dtype: object
लागू करने के अभी भी ऊपर के तरीकों के रूप में सभी मुद्दे हैं।
for i, (a, b, c) in enumerate(some_function_that_yields_data()):
df.iloc[i] = [a, b, c]
खुद के मरने से स्वर्ग मिलता है
इन तरीकों को समय पर देखने का सबसे तेज़ तरीका है कि वे अपनी स्मृति और उपयोगिता के मामले में कितना भिन्न हैं।
संदर्भ के लिए बेंचमार्किंग कोड।