क्या मुझे डेटा.फ्रेम या मैट्रिक्स का उपयोग करना चाहिए?


152

कब एक का उपयोग करना चाहिए data.frame, और कब उपयोग करना बेहतर है matrix?

दोनों एक आयताकार प्रारूप में डेटा रखते हैं, इसलिए कभी-कभी यह अस्पष्ट है।

कब किस डेटा प्रकार का उपयोग करना है, इसके लिए अंगूठे के कोई सामान्य नियम हैं?


अक्सर मैट्रिक्स एक विशेष प्रकार के डेटा के लिए बेहतर अनुकूल हो सकता है, लेकिन यदि आप जिस पैकेज का विश्लेषण करने के लिए उपयोग करना चाहते हैं, वह मैट्रिक्स को डेटा फ़्रेम की उम्मीद करता है, तो आपको हमेशा इसे अनावश्यक रूप से परिवर्तित करना होगा। मुझे लगता है कि रीमेकिंग से बचने का कोई तरीका नहीं है जो पैकेज का उपयोग करता है।
xApple

जवाबों:


176

उत्तर का हिस्सा आपके प्रश्न में पहले से ही निहित है: आप डेटा फ़्रेम का उपयोग करते हैं यदि कॉलम (चर) विभिन्न प्रकारों (संख्यात्मक / चरित्र / तार्किक आदि) से होने की उम्मीद की जा सकती है। मैटरिस उसी प्रकार के डेटा के लिए हैं।

नतीजतन, यदि आपके पास एक ही प्रकार का डेटा है, तो विकल्प मैट्रिक्स / data.frame केवल समस्याग्रस्त है।

उत्तर इस बात पर निर्भर करता है कि आप डेटा में डेटा के साथ क्या करने जा रहे हैं। यदि यह अन्य कार्यों के लिए पारित होने जा रहा है, तो इन कार्यों के तर्क के अपेक्षित प्रकार विकल्प का निर्धारण करते हैं।

इसके अलावा:

मैट्रिसेस अधिक मेमोरी कुशल हैं:

m = matrix(1:4, 2, 2)
d = as.data.frame(m)
object.size(m)
# 216 bytes
object.size(d)
# 792 bytes

यदि आप किसी भी रैखिक बीजगणित-प्रकार के ऑपरेशन करने की योजना बनाते हैं, तो मैट्रिस एक आवश्यकता है।

यदि आप अक्सर इसके कॉलम को नाम से (कॉम्पैक्ट $ ऑपरेटर के माध्यम से) संदर्भित करते हैं, तो डेटा फ़्रेम अधिक सुविधाजनक होते हैं।

डेटा फ़्रेम भी रिपोर्टिंग (प्रिंटिंग) सारणीबद्ध जानकारी के लिए बेहतर है, क्योंकि आप प्रत्येक कॉलम को अलग से स्वरूपण लागू कर सकते हैं।


5
एक बात मैं इस जवाब में जोड़ दूंगा कि अगर आप ग्राफ बनाने के लिए ggplot2 पैकेज का उपयोग करने की योजना बनाते हैं, तो ggplot2 केवल डेटा.फ्रेम और मेट्रिसेस के साथ काम करता है। बस ऐसा कुछ जिसके बारे में अवगत होना चाहिए!
बाजीग

77

@ मिचल के द्वारा उल्लेखित कुछ भी नहीं है कि न केवल बराबर डेटा फ्रेम से छोटा मैट्रिक्स है, मैट्रिस का उपयोग करने से आपके कोड को डेटा फ्रेम का उपयोग करने की तुलना में कहीं अधिक कुशल बनाया जा सकता है, अक्सर ऐसा होता है। यही कारण है कि आंतरिक रूप से, बहुत सारे आर फ़ंक्शन डेटा फ़्रेम में मौजूद डेटा को परिपक्व करने के लिए बाध्य करेंगे।

डेटा फ़्रेम अक्सर अधिक सुविधाजनक होते हैं; एक के पास हमेशा केवल डेटा के परमाणु विखंडन नहीं होते हैं।

ध्यान दें कि आपके पास एक चरित्र मैट्रिक्स हो सकता है; R में मैट्रिक्स बनाने के लिए आपके पास केवल संख्यात्मक डेटा होना आवश्यक नहीं है।

किसी डेटा फ़्रेम को मैट्रिक्स में कनवर्ट करने में, ध्यान दें कि एक data.matrix()फ़ंक्शन है, जो कारकों को आंतरिक स्तरों के आधार पर संख्यात्मक मानों में परिवर्तित करके उचित रूप से संभालता है। as.matrix()यदि कोई भी कारक लेबल गैर-संख्यात्मक है, तो उसके माध्यम से जोर लगाने से चरित्र मैट्रिक्स उत्पन्न होगा। की तुलना करें:

> head(as.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
     a   B  
[1,] "a" "A"
[2,] "b" "B"
[3,] "c" "C"
[4,] "d" "D"
[5,] "e" "E"
[6,] "f" "F"
> head(data.matrix(data.frame(a = factor(letters), B = factor(LETTERS))))
     a B
[1,] 1 1
[2,] 2 2
[3,] 3 3
[4,] 4 4
[5,] 5 5
[6,] 6 6

मैं लगभग हमेशा अपने डेटा विश्लेषण कार्यों के लिए डेटा फ़्रेम का उपयोग करता हूं क्योंकि मेरे पास अक्सर केवल संख्यात्मक चर से अधिक होते हैं। जब मैं पैकेज के लिए फ़ंक्शन करता हूं, तो मैं लगभग हमेशा मैट्रिक्स के साथ तालमेल करता हूं और फिर परिणामों को डेटा फ़्रेम के रूप में वापस स्वरूपित करता हूं। ऐसा इसलिए है क्योंकि डेटा फ़्रेम सुविधाजनक हैं।


मैं data.matrix () और as.matrix () के बीच का अंतर भी सोच रहा हूं। प्रोग्रामिंग में उन्हें और आपकी युक्तियों को स्पष्ट करने के लिए धन्यवाद।
माइक्रोब

@Gavin सिम्पसन साझा करने के लिए धन्यवाद! क्या आप थोड़ा और परिचय दे सकते हैं कि 1-6 से ऊपर तक कैसे वापस जाएं?
YJZ

1
@YZhang आपको प्रत्येक कारक के लिए लेबलों को संग्रहीत करने की आवश्यकता होगी और यह दर्शाता है कि मैट्रिक्स के कौन से कॉलम कारक हैं। फिर यह केवल उन स्तंभों को बदलने के लिए अपेक्षाकृत तुच्छ होगा जो कारकों में वापस सही लेबल के साथ कारक थे। टिप्पणियाँ कोड के लिए अच्छी जगहें नहीं हैं, इसलिए देखें कि क्या प्रश्न पहले पूछा गया है और उत्तर दिया गया है या नहीं।
गैविन सिम्पसन

47

@ मिचल: मैट्रिस वास्तव में अधिक मेमोरी कुशल नहीं हैं:

m <- matrix(1:400000, 200000, 2)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 1600776 bytes

... जब तक आपके पास बड़ी संख्या में कॉलम न हों:

m <- matrix(1:400000, 2, 200000)
d <- data.frame(m)
object.size(m)
# 1600200 bytes
object.size(d)
# 22400568 bytes

स्मृति दक्षता तर्क वास्तव में data.framesस्तंभ प्रकारों पर अधिक लचीलापन प्रदान करने के बारे में है । प्रकार की कमी के कारण संस्करण की data.frame(a = rnorm(1e6), b = sample(letters, 1e6, TRUE))तुलना में स्मृति में बहुत कम (मेरी त्वरित गणना द्वारा 6x) होगा matrix
माइकलक्रिको

9

मैट्रिक्स वास्तव में अतिरिक्त विधियों के साथ एक वेक्टर है। जबकि data.frame एक सूची है। यह अंतर वेक्टर बनाम सूची में नीचे है। अभिकलन दक्षता के लिए, मैट्रिक्स के साथ छड़ी। यदि आपको करना है तो डेटा.फ्रेम का उपयोग करना।


3
हम्म, एक मैट्रिक्स आयामों के साथ एक वेक्टर है, मैं यह नहीं देखता कि इसमें विधियां कहां से आती हैं?
गैविन सिम्पसन

0

मैट्रिक्स और डेटा फ़्रेम आयताकार 2 डी सरणियां हैं और पंक्तियों और स्तंभों द्वारा विषम हो सकती हैं । वे कुछ तरीके और गुण साझा करते हैं, लेकिन सभी नहीं।

उदाहरण:

M <- list(3.14,TRUE,5L,c(2,3,5),"dog",1i)  # a list
dim(M) <- c(2,3)                           # set dimensions
print(M)                                   # print result

#      [,1]  [,2]      [,3]
# [1,] 3.14  5         "dog"
# [2,] TRUE  Numeric,3 0+1i

DF <- data.frame(M)                   # a data frame
print(DF)                             # print result

#      X1      X2   X3
#  1 3.14       5  dog
#  2 TRUE 2, 3, 5 0+1i

M <- matrix(c(1,1,1,1,2,3,1,3,6),3)   # a numeric matrix
DF <- data.frame(M)                   # a all numeric data frame

solve(M)                              # obtains inverse matrix
solve(DF)                             # obtains inverse matrix
det(M)                                # obtains determinant
det(DF)                               # error

0

मैं दोनों के बीच अधिक दक्षता अंतर पर जोर नहीं दे सकता! हालांकि यह सच है कि कुछ विशेष रूप से डेटा विश्लेषण मामलों में DFs अधिक सुविधाजनक हैं, वे विषम डेटा की भी अनुमति देते हैं, और कुछ पुस्तकालय उन्हें केवल स्वीकार करते हैं, ये सभी वास्तव में माध्यमिक हैं जब तक कि आप किसी विशिष्ट कार्य के लिए एक बार कोड नहीं लिखते हैं।

मैं आपको एक उदाहरण देता हूं। एक फ़ंक्शन था जो MCMC विधि के 2D पथ की गणना करेगा। मूल रूप से, इसका मतलब है कि हम एक प्रारंभिक बिंदु (एक्स, वाई) लेते हैं, और प्रत्येक चरण पर एक नया बिंदु (एक्स, वाई) खोजने के लिए एक निश्चित एल्गोरिथ्म को पूरा करते हैं, इस तरह से पूरे रास्ते का निर्माण करते हैं। एल्गोरिथ्म में प्रत्येक पुनरावृत्ति पर एक काफी जटिल फ़ंक्शन और कुछ यादृच्छिक चर की पीढ़ी की गणना करना शामिल है, इसलिए जब यह 12 सेकंड के लिए चलता है तो मुझे लगा कि यह ठीक है कि यह प्रत्येक चरण में कितना सामान देता है। कहा जा रहा है, फ़ंक्शन ने 3-कॉलम डेटा.फ्रेम में एक उद्देश्य फ़ंक्शन के मूल्य के साथ निर्माण पथ में सभी बिंदुओं को एकत्र किया। तो, 3 कॉलम बड़े नहीं हैं, और चरणों की संख्या भी उचित 10,000 से अधिक थी (इस तरह की समस्याओं में 1,000,000 1,000,000 की लंबाई विशिष्ट होती है, इसलिए 10,000 कुछ भी नहीं है)। तो, मैंने सोचा कि एक DF 10, 000x3 निश्चित रूप से एक मुद्दा नहीं है। डीएफ का उपयोग करने का कारण सरल है। फ़ंक्शन को कॉल करने के बाद, परिणाम (x, y) -पथ को आकर्षित करने के लिए ggplot () को बुलाया गया था। और ggplot () मैट्रिक्स को स्वीकार नहीं करता है।

फिर, जिज्ञासा से बाहर कुछ बिंदु पर मैंने मैट्रिक्स में पथ एकत्र करने के लिए फ़ंक्शन को बदलने का फैसला किया। ख़ुशी से DFs और मैट्रिसेस का सिंटैक्स समान है, मैंने केवल एक डेटा के रूप में df निर्दिष्ट करने वाली लाइन को बदलना था। एक मैट्रिक्स के रूप में इसे इनिशियलाइज़ करने के लिए। यहां मुझे यह भी उल्लेख करना होगा कि प्रारंभिक कोड में DF को अंतिम आकार के लिए आरंभीकृत किया गया था, इसलिए बाद में फ़ंक्शन के कोड में केवल नए मान पहले से आवंटित स्थान में दर्ज किए गए थे, और नई पंक्तियों को जोड़ने के लिए कोई उपरि नहीं थी DF। यह तुलना को और अधिक उचित बनाता है, और इसने मेरे काम को भी सरल बना दिया क्योंकि मुझे फ़ंक्शन में आगे कुछ भी लिखने की आवश्यकता नहीं थी। डेटा के प्रारंभिक आवंटन से बस एक पंक्ति बदल जाती है। समान आकार के मैट्रिक्स के लिए आवश्यक आकार का समायोजन। फ़ंक्शन के नए संस्करण को ggplot () में बदलने के लिए, मैंने अब लौटे मैट्रिक्स को एक डेटा में बदल दिया।

कोड को पुन: चलाने के बाद मैं परिणाम पर विश्वास नहीं कर सका। कोड एक सेकंड के एक अंश में चलता है! इसके बजाय लगभग 12 सेकंड। और फिर, 10,000 पुनरावृत्तियों के दौरान फ़ंक्शन केवल डीएफ (और अब मैट्रिक्स में) में पहले से ही आवंटित रिक्त स्थान के मूल्यों को पढ़ता और लिखता है। और यह अंतर भी उचित (या बल्कि छोटे) आकार 10000x3 के लिए है।

इसलिए, यदि आपका DF का उपयोग करने का एकमात्र कारण इसे लाइब्रेरी फ़ंक्शन जैसे ggplot () के साथ संगत बनाना है, तो आप हमेशा इसे अंतिम क्षण में DF में परिवर्तित कर सकते हैं - जहां तक ​​आपको सुविधाजनक लगे, मैट्रिसेस के साथ काम करें। यदि दूसरी ओर DF का उपयोग करने के लिए अधिक पर्याप्त कारण है, जैसे कि आप कुछ डेटा विश्लेषण पैकेज का उपयोग करते हैं, जिसके लिए अन्यथा मैट्रिस से DFs और बैक में लगातार परिवर्तन की आवश्यकता होगी, या आप स्वयं कोई गहन गणना नहीं करते हैं और केवल मानक का उपयोग करते हैं पैकेज (उनमें से कई वास्तव में आंतरिक रूप से एक DF को मैट्रिक्स में बदल देते हैं, अपना काम करते हैं, और फिर परिणाम को वापस बदल देते हैं - इसलिए वे आपके लिए सभी कार्य कुशलता से करते हैं), या एक बार का काम करते हैं ताकि आप परवाह न करें और महसूस करें DFs के साथ अधिक आरामदायक है, तो आपको दक्षता के बारे में चिंता नहीं करनी चाहिए।

या एक और अधिक व्यावहारिक नियम: यदि आपके पास एक प्रश्न है जैसे कि ओपी में, मैट्रिस का उपयोग करें, तो आप केवल DFs का उपयोग करेंगे जब आपके पास ऐसा प्रश्न नहीं होगा (क्योंकि आप पहले से ही जानते हैं कि आपको DFs का उपयोग करना होगा, या क्योंकि आप करते हैं वास्तव में परवाह नहीं है क्योंकि कोड एक बार आदि है)।

लेकिन सामान्य तौर पर इस दक्षता बिंदु को प्राथमिकता के रूप में हमेशा ध्यान में रखें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.