2012-12-13 12 views
15

एक और पांडा प्रश्न काम नहीं करता है।पांडा 'ट्रांसफॉर्म सॉर्टिंग ग्रुपबी आउटपुट

मान लीजिए मैं सुझावों के बारे में कुछ जानकारी है:

डेटा विश्लेषण और पांडा के बारे में पढ़ना वेस Mckinney उत्तम पुस्तक, मैं निम्नलिखित बात यह है कि मैंने सोचा था कि काम करना चाहिए का सामना करना पड़ा।

In [119]: 

tips.head() 
Out[119]: 
total_bill tip  sex  smoker day time size tip_pct 
0 16.99 1.01 Female False Sun  Dinner 2 0.059447 
1 10.34 1.66 Male False Sun  Dinner 3 0.160542 
2 21.01 3.50 Male False Sun  Dinner 3 0.166587 
3 23.68 3.31 Male False Sun  Dinner 2 0.139780 
4 24.59 3.61 Female False Sun  Dinner 4 0.146808 

और मैं कुल बिल के संबंध में पांच सबसे बड़े सुझावों को पता है, कि है, धूम्रपान करने वालों और गैर धूम्रपान करने वालों के लिए tip_pct अलग करना चाहते हैं। तो यह काम करता है:

def top(df, n=5, column='tip_pct'): 
    return df.sort_index(by=column)[-n:] 

In [101]: 

tips.groupby('smoker').apply(top) 
Out[101]: 
      total_bill tip sex smoker day time size tip_pct 
smoker         
False 88 24.71 5.85 Male False Thur Lunch 2 0.236746 
185 20.69 5.00 Male False Sun  Dinner 5 0.241663 
51 10.29 2.60 Female False Sun  Dinner 2 0.252672 
149 7.51 2.00 Male False Thur Lunch 2 0.266312 
232 11.61 3.39 Male False Sat  Dinner 2 0.291990 

True 109 14.31 4.00 Female True Sat  Dinner 2 0.279525 
183 23.17 6.50 Male True Sun  Dinner 4 0.280535 
67 3.07 1.00 Female True Sat  Dinner 1 0.325733 
178 9.60 4.00 Female True Sun  Dinner 2 0.416667 
172 7.25 5.15 Male True Sun  Dinner 2 0.710345 

अच्छा पर्याप्त है, लेकिन फिर मैं पांडा उपयोग करने के लिए 'इस तरह भी ऐसा ही करने को बदलने चाहता था:

def top_all(df): 
    return df.sort_index(by='tip_pct') 

tips.groupby('smoker').transform(top_all) 

लेकिन इसके बजाय मैं इस मिल:

TypeError: Transform function invalid for data types 

क्यूं कर? मुझे पता है कि ट्रांसफॉर्म को उसी आयाम की एक सरणी वापस करने की आवश्यकता है जो इसे इनपुट के रूप में स्वीकार करता है, इसलिए मैंने सोचा कि मैं उस आवश्यकता के साथ अनुपालन कर रहा हूं, मूल डेटाफ्रेम के दोनों स्लाइस (धूम्रपान करने वालों और धूम्रपान करने वालों) को अपने संबंधित आयामों को बदले बिना सॉर्ट करना । क्या कोई समझा सकता है कि यह क्यों विफल रहा?

उत्तर

36

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

तो tips.groupby('smoker').transform(func) मान लीजिए। दो समूह होंगे, उन्हें समूह 1 और समूह 2 कहें। ट्रांसफॉर्म func(group1) और func(group2) पर कॉल नहीं करता है। इसके बजाय, यह func(group1['total_bill']), फिर func(group1['tip']), आदि, और फिर func(group2['total_bill']), func(group2['total_bill']) पर कॉल करता है।

>>> print d 
    A B C 
0 -2 5 4 
1 1 -1 2 
2 0 2 1 
3 -3 1 2 
4 5 0 2 
>>> def foo(df): 
...  print ">>>" 
...  print df 
...  print "<<<" 
...  return df 
>>> print d.groupby('C').transform(foo) 
>>> 
2 0 
Name: A 
<<< 
>>> 
2 2 
Name: B 
<<< 
>>> 
1 1 
3 -3 
4 5 
Name: A 
<<< 
>>> 
1 -1 
3 1 
4 0 
Name: B 
# etc. 

आप देख सकते हैं कि foo पहले सिर्फ मूल डेटा फ्रेम के सी = 1 समूह का एक स्तंभ, उस समूह का तो बी स्तंभ है, तो का एक स्तंभ के साथ कहा जाता है: यहाँ एक उदाहरण है सी = 2 समूह, आदि

यह समझ में आता है कि क्या आप सोचते हैं कि किस बदलाव के लिए है। यह समूहों पर परिवर्तन कार्यों को लागू करने के लिए है। लेकिन आम तौर पर, पूरे समूह पर लागू होने पर, केवल एक दिए गए कॉलम पर इन कार्यों को समझ में नहीं आता है। उदाहरण के लिए, पांडा दस्तावेज़ों में उदाहरण transform का उपयोग कर जेड-मानकीकरण के बारे में है। यदि आपके पास उम्र और वजन के लिए कॉलम वाले डेटाफ्रेम हैं, तो इन दोनों चर के समग्र माध्य के संबंध में जेड-मानकीकरण करने का अर्थ नहीं होगा। इसका मतलब यह भी नहीं है कि संख्याओं के समूह का समग्र अर्थ लेने के लिए कुछ भी है, जिनमें से कुछ उम्र हैं और इनमें से कुछ वजन हैं। आपको औसत आयु और औसत वजन के संबंध में वजन के संबंध में आयु को ज़ेड-मानकीकृत करना है, जिसका अर्थ है कि आप प्रत्येक कॉलम के लिए अलग-अलग रूपांतरित करना चाहते हैं।

तो मूल रूप से, आपको यहां परिवर्तन का उपयोग करने की आवश्यकता नहीं है। apply यहां उचित कार्य है, क्योंकि apply वास्तव में प्रत्येक समूह पर एक ही डेटाफ्रेम के रूप में काम करता है, जबकि transform प्रत्येक समूह के प्रत्येक कॉलम पर चलता है।

+1

उत्कृष्ट उत्तर। आपका बहुत बहुत धन्यवाद! –

+6

इतना खराब दस्तावेज क्यों बदल रहा है? ये मुझे पागल कर रहा है।मुझे नहीं लगता कि आपके पास यह सही है हालांकि (हालांकि मुझे नहीं पता कि यह वास्तव में कैसे काम कर रहा है) जब आप अपने कार्यों में प्रिंट स्टेटमेंट डालते हैं तो यह स्पष्ट लगता है कि ट्रांसफॉर्म वास्तव में श्रृंखला और डेटा फ्रेम के रूप में कॉलम पास कर रहा है। यह वास्तव में डरावना है और मैं समझना चाहता हूं कि दृश्यों के पीछे क्या चल रहा है लेकिन वास्तव में इसे कैसे कार्यान्वित किया जाता है इस पर कोई जानकारी नहीं मिल सकती है। –

संबंधित मुद्दे