2014-12-12 10 views
12

कम नहीं करता है मैं एक समेकन फ़ंक्शन का उपयोग कर रहा हूं जिसे मैंने लंबे समय से अपने काम में उपयोग किया है। विचार यह है कि यदि समारोह में पारित श्रृंखला लंबाई 1 है (यानी समूह में केवल एक अवलोकन है) तो अवलोकन वापस कर दिया जाता है। यदि श्रृंखला पारित की लंबाई एक से अधिक है, तो अवलोकन एक सूची में वापस कर दिया जाता है।पांडस ग्रुपबी एजीजी फंक्शन

यह कुछ के लिए अजीब लग सकता है, लेकिन यह एक्स, वाई समस्या नहीं है, मेरे पास ऐसा करने के लिए अच्छा कारण है जो इस प्रश्न से प्रासंगिक नहीं है।

def MakeList(x): 
    """ This function is used to aggregate data that needs to be kept distinc within multi day 
     observations for later use and transformation. It makes a list of the data and if the list is of length 1 
     then there is only one line/day observation in that group so the single element of the list is returned. 
     If the list is longer than one then there are multiple line/day observations and the list itself is 
     returned.""" 
    L = x.tolist() 
    if len(L) > 1: 
     return L 
    else: 
     return L[0] 

अब किसी कारण से, वर्तमान डेटा सेट मैं मैं पर काम कर रहा हूँ के साथ मिल एक ValueError करते हुए कहा कि समारोह को कम नहीं करता:

इस समारोह है कि मैं का उपयोग किया गया है। यहाँ कुछ परीक्षण डाटा और शेष चरणों मैं उपयोग कर रहा हूँ है:

import pandas as pd 
DF = pd.DataFrame({'date': ['2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02', 
          '2013-04-02'], 
        'line_code': ['401101', 
            '401101', 
            '401102', 
            '401103', 
            '401104', 
            '401105', 
            '401105', 
            '401106', 
            '401106', 
            '401107'], 
        's.m.v.': [ 7.760, 
           25.564, 
           25.564, 
           9.550, 
           4.870, 
           7.760, 
           25.564, 
           5.282, 
           25.564, 
           5.282]}) 
DFGrouped = DF.groupby(['date', 'line_code'], as_index = False) 
DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList}) 

इस डिबग करने के लिए कोशिश कर रहा में, मैं print L और print x.index और के प्रभाव आउटपुट के रूप में था करने के लिए एक प्रिंट बयान डाल इस प्रकार है:

[7.7599999999999998, 25.564] 
Int64Index([0, 1], dtype='int64') 
[7.7599999999999998, 25.564] 
Int64Index([0, 1], dtype='int64') 

किसी कारण से ऐसा लगता है कि agg फ़ंक्शन में श्रृंखला को दो बार गुजर रहा है। जहां तक ​​मुझे पता है कि यह बिल्कुल सामान्य नहीं है, और संभवत: मेरा कार्य कम नहीं होने का कारण है।

उदाहरण के लिए अगर मैं इस तरह एक समारोह लिखें:

def test_func(x): 
    print x.index 
    return x.iloc[0] 

यह समस्या के बिना चलाता है और प्रिंट बयान कर रहे हैं:

DF_Agg = DFGrouped.agg({'s.m.v.' : test_func}) 

Int64Index([0, 1], dtype='int64') 
Int64Index([2], dtype='int64') 
Int64Index([3], dtype='int64') 
Int64Index([4], dtype='int64') 
Int64Index([5, 6], dtype='int64') 
Int64Index([7, 8], dtype='int64') 
Int64Index([9], dtype='int64') 

जो इंगित करता है कि प्रत्येक समूह में ही एक के रूप में एक बार पारित किया जा रहा है समारोह के लिए श्रृंखला।

क्या कोई मुझे यह समझने में सहायता कर सकता है कि यह क्यों विफल रहा है? मैं कई डेटा सेट के साथ मैं ....

धन्यवाद काम में सफलता के साथ इस समारोह का इस्तेमाल किया है

+1

यह संभव है कि यदि आपका कार्य कभी-कभी एक सूची और कभी-कभी एक मूल्य लौटाता है तो पांडा भ्रमित हो जाते हैं, क्योंकि उन दो मामलों के लिए अलग-अलग प्रकार का उपयोग किया जाएगा। यह संभवतः ऐसा करने के लिए बेहतर नहीं है। कॉलिंग-दो बार व्यवहार [लागू] के लिए वर्णित मुद्दे से संबंधित हो सकता है [http://stackoverflow.com/questions/21390035/python-pandas-groupby-object-apply-method-duplicates- फर्स्ट- समूह) 'लागू' के लिए : यह जांचने के लिए कि क्या फ़ंक्शन मौजूदा डेटा को बदलता है या नहीं, यह पहले समूह पर फ़ंक्शन को दो बार कॉल करता है। – BrenBarn

+0

हमम .... मुझे शायद वस्तु प्रकार के रूप में सेट करने का प्रयास करना चाहिए। –

+0

अजीब बात यह है कि, मैं इस समस्या को हर समय बिना किसी समस्या के पुन: उपयोग करता हूं। मुझे पता है कि डेटा के अलग-अलग पैकेट को पास और ट्रांसफर करना है, जैसे कि प्रिंट स्टेटमेंट्स से पता लगाना मुश्किल है, लेकिन एह काफी सरल है। क्या आप त्रुटि को फिर से बनाने में सक्षम थे? –

उत्तर

24

मैं वास्तव में आप की व्याख्या नहीं कर सकते हैं क्यों, लेकिन मेरे अनुभव से listpandas.DataFrame में बिल्कुल काम नहीं करते कि कुंआ।

मैं आमतौर पर tuple का उपयोग करता हूं। काम करेंगे कि:

def MakeList(x): 
    T = tuple(x) 
    if len(T) > 1: 
     return T 
    else: 
     return T[0] 

DF_Agg = DFGrouped.agg({'s.m.v.' : MakeList}) 

    date line_code   s.m.v. 
0 2013-04-02 401101 (7.76, 25.564) 
1 2013-04-02 401102   25.564 
2 2013-04-02 401103    9.55 
3 2013-04-02 401104    4.87 
4 2013-04-02 401105 (7.76, 25.564) 
5 2013-04-02 401106 (5.282, 25.564) 
6 2013-04-02 401107   5.282 
+3

के बजाय' tuple (एल) 'वापस करना है, इस तथ्य के साथ यह करना है कि' tuple' प्रकार अपरिवर्तनीय है और इसलिए हैशबल और 'सूची' नहीं है। –

+0

शायद! लेकिन अवधारणा परिप्रेक्ष्य में "कुल नहीं है" से समान हैं, इसलिए अनुमान लगाने का कोई तरीका नहीं है कि कुछ काम नहीं करेंगे बी/सी आप सूचियों का उपयोग कर रहे हैं और tuples नहीं। अच्छा पकड़ा! – Ufos

6

यह DataFrame में एक misfeature है। यदि एग्रीगेटर पहले समूह के लिए एक सूची देता है, तो यह आपके द्वारा उल्लिखित त्रुटि के साथ विफल हो जाएगा; यदि यह पहले समूह के लिए एक गैर-सूची (गैर-श्रृंखला) देता है, तो यह ठीक काम करेगा। टूटी हुई कोड groupby.py में है:

def _aggregate_series_pure_python(self, obj, func): 

    group_index, _, ngroups = self.group_info 

    counts = np.zeros(ngroups, dtype=int) 
    result = None 

    splitter = get_splitter(obj, group_index, ngroups, axis=self.axis) 

    for label, group in splitter: 
     res = func(group) 
     if result is None: 
      if (isinstance(res, (Series, Index, np.ndarray)) or 
        isinstance(res, list)): 
       raise ValueError('Function does not reduce') 
      result = np.empty(ngroups, dtype='O') 

     counts[label] = group.shape[0] 
     result[label] = res 

सूचना है कि if result is None और isinstance(res, list। आपके विकल्प हैं:

  1. ग्रुपबी() को नकली करें।agg(), इसलिए यह पहले समूह के लिए कोई सूची नहीं देखता है, या

  2. उपरोक्त कोड का उपयोग करके, लेकिन गलत परीक्षण के बिना स्वयं को एकत्रीकरण करें।

+0

जैसा कि अन्य उत्तर 'tuple' में बताया गया है, ठीक काम करेगा। उपरोक्त फ़ंक्शन निश्चित रूप से बी/सी यह जांच नहीं करता है कि ऑब्जेक्ट एक 'tuple' है या नहीं। बग या एक सुविधा - आप तय करते हैं! – Ufos

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