2016-07-20 5 views
0

So scheint es, dass meine gorupby nicht funktioniert, wenn ich versuche, mehr Parameter für die Funktion, die ich mit meiner groupby anwenden anwenden anwenden.Pandas groupby nicht funktioniert mit Wrong Anzahl der Elemente bestanden 4, Platzierung impliziert 1

Ich habe etwas gefunden, das hier wie mein Szenario aussieht: http://pbpython.com/weighted-average.html im Abschnitt ‚Gruppieren von Daten mit dem gewichteten Durchschnitt‘ um halb nach unten dem Artikel.

Ich versuche meine Funktion zu verwenden, wo 2 Spalten von der df als Parameter benötigt werden, um meine Berechnung durchzuführen.

Mein Code

import pandas as pd 
from io import StringIO 

text = """Ticker Date Adj_Close Volume MACD emaSlw emaFst MACDsig MACDperc 
A 18-07-2016 46.8 1362900.0 0.55 45.81 45.26 0.21 -0.9954 
A 19-07-2016 46.98 2579000.0 0.6 45.99 45.39 0.29 -0.9937 
AA 18-07-2016 10.92 16297800.0 0.32 10.27 9.94 0.1 -0.99 
AA 19-07-2016 10.63 14316200.0 0.33 10.32 9.99 0.15 -0.9856 
AAL 18-07-2016 36.03 8604200.0 1.15 32.84 31.69 -0.08 -10.023 
AAL 19-07-2016 36.01 7928100.0 1.32 33.33 32.01 0.19 -0.9942 
AAP 18-07-2016 164.4 516800.0 2.83 162.59 159.75 2.72 -0.9832 
AAP 19-07-2016 163.7 854700.0 2.71 162.76 160.05 2.76 -0.983 
AAPL 18-07-2016 99.83 36439900.0 0.5 97.36 96.86 -0.16 -10.017 
AAPL 19-07-2016 99.87 23703900.0 0.67 97.75 97.08 -0.01 -10.001 
ABBV 18-07-2016 63.56 6384800.0 0.9 63.06 62.16 0.71 -0.9887 
ABBV 19-07-2016 63.32 5716800.0 0.86 63.1 62.25 0.78 -0.9876 
ABC 18-07-2016 86.03 1113600.0 2.31 82.91 80.6 1.52 -0.9817 
ABC 19-07-2016 85.92 1975400.0 2.38 83.38 81.0 1.7 -0.9796 
ABT 18-07-2016 42.09 7524200.0 1.05 41.14 40.09 0.75 -0.9818 
ABT 19-07-2016 41.8 8395400.0 1.02 41.24 40.22 0.84 -0.9796""" 

df = pd.read_csv(StringIO(text), delim_whitespace=1, parse_dates=[0], index_col=1) 

df.drop(['Volume', 'emaSlw', 'emaFst'],inplace=True,axis=1) 

def Trade_signal_calc(group): 

    if df['MACD'].irow(-1) > 0: # MACD is pos. so trade (BUY/Sell) 
     # BUY signals 
     # if todays MACD is higher than signal, AND yesturday's MACD was lower than signal 
     if (df['MACD'].irow(-1) > df['MACDsig'].irow(-1)) \ 
     & (df['MACD'].irow(-2) < df['MACDsig'].irow(-2)) : 
      df['Trade'] = 'Buy' 
      return df 
     # SELL signals 
     # if todays MACD is lower than signal, AND yesturday's MACD was higher than signal - reverse the above 
     elif (df['MACD'].irow(-1) < df['MACDsig'].irow(-1)) \ 
     & ((df['MACD'].irow(-2)) > df['MACDsig'].irow(-2)) : 
      df['Trade'] = 'Sell' 
      return df 
     else: # No strong Buy or Sell signals 
      return df 
    else: # MACD is neg. so don't trade 
     return df 


if __name__ == '__main__': 

    # Multiindex Needed for my groupby to work properly ??? 
    df = df.set_index('Ticker', append=True) 
    print ('\ndf \n%s\n---------------------------------\nMultiindex df\n%s' %(df.iloc[0:4,0:6], df.iloc[0:4,0:6]))  

    df['Trade'] = df.groupby(level='Ticker')[['MACD','MACDsig']].apply(Trade_signal_calc) 
    print ('\ndf with Buy & Sell signals \ndfTrade shows trades from MACD & MACDsig comparison (summary from df) (Output)\n%s\nSignals: \nBuy: (df(MACD[-1]) > df(MACDsig[-1])) & (df(MACD[-2]) < df(MACDsig[-2])) \nSell: (df(MACD[-1]) < df(MACDsig[-1])) & (df(MACD[-2]) > df(MACDsig[-2])) \n\n%s' %(75*'-',df[['Trade','MACD','MACDsig','Adj_Close','Date']])) 
    # Resetting index from before doing groupby w. multi-index 
    df = df.reset_index('Ticker')  

    # Test the first 3 rows of each group for 'Difference' col transgress groups... 
    df = df.groupby('Ticker').head(3).reset_index().set_index('Date') 
    print ('\ndf (summary from df) (Output)\n',df,'\n') 

Aber wenn ich versuche, es in meinem Code anwenden bekomme ich einen Fehler.

df 
        Adj_Close MACD MACDsig MACDperc 
Date  Ticker          
18-07-2016 A   46.80 0.55  0.21 -0.9954 
19-07-2016 A   46.98 0.60  0.29 -0.9937 
18-07-2016 AA   10.92 0.32  0.10 -0.9900 
19-07-2016 AA   10.63 0.33  0.15 -0.9856 
--------------------------------- 
Multiindex df 
        Adj_Close MACD MACDsig MACDperc 
Date  Ticker          
18-07-2016 A   46.80 0.55  0.21 -0.9954 
19-07-2016 A   46.98 0.60  0.29 -0.9937 
18-07-2016 AA   10.92 0.32  0.10 -0.9900 
19-07-2016 AA   10.63 0.33  0.15 -0.9856 
Traceback (most recent call last): 

    File "<ipython-input-27-d88b1f547887>", line 1, in <module> 
    runfile('C:/Users/Morten/Documents/Design/Python/CrystalBall - Local - Git/Git - CrystalBall/sandbox/test_groupby_multiple_Input_Cols.py', wdir='C:/Users/Morten/Documents/Design/Python/CrystalBall - Local - Git/Git - CrystalBall/sandbox') 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 682, in runfile 
    execfile(filename, namespace) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 85, in execfile 
    exec(compile(open(filename, 'rb').read(), filename, 'exec'), namespace) 

    File "C:/Users/Morten/Documents/Design/Python/CrystalBall - Local - Git/Git - CrystalBall/sandbox/test_groupby_multiple_Input_Cols.py", line 63, in <module> 
    df['Trade'] = df.groupby(level='Ticker')[['MACD','MACDsig']].apply(Trade_signal_calc) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\frame.py", line 2117, in __setitem__ 
    self._set_item(key, value) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\frame.py", line 2195, in _set_item 
    NDFrame._set_item(self, key, value) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\generic.py", line 1190, in _set_item 
    self._data.set(key, value) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\internals.py", line 2975, in set 
    self.insert(len(self.items), item, value) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\internals.py", line 3074, in insert 
    placement=slice(loc, loc+1)) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\internals.py", line 2093, in make_block 
    placement=placement) 

    File "C:\Program Files\WinPython-64bit-3.3.5.7_2ndInst\python-3.3.5.amd64\lib\site-packages\pandas\core\internals.py", line 77, in __init__ 
    len(self.values), len(self.mgr_locs))) 

ValueError: Wrong number of items passed 4, placement implies 1 

Es scheint wie ein Parameterfehler, aber ich verwende keine params andere als die groupby Objekt ‚Gruppe‘ in der Trade_signal_calc (Gruppe) -Aufruf.

In meinem Code habe ich den Fehler korrigiert, EdChum wies darauf hin. Danke Ed.

Hat jemand eine Idee, was ist falsch mit meinem Code?

Antwort

0

Fügen Sie zusätzliche [] um Ihre Spalte Auswahl:

df['Trade'] = df.groupby(level=1)[['MACD','MACDsig']].apply(Trade_signal_calc, 'MACD','MACDsig') 

Der Fehler ist Ihnen zu sagen, dass kein Schlüssel vorhanden ist, wie es ist Ihre Wahl als Tupel zu behandeln, das ist nicht anders zu tun:

df['Trade'] = df['MACD','MACDsig'].groupby(level=1).apply(Trade_signal_calc, 'MACD','MACDsig') 

Wenn Sie die Syntax auf diese Weise sehen, können Sie sehen, warum es fehlschlägt, so müssen Sie zusätzliche [] hinzufügen, so dass es eine Liste von Spalten wird

+0

Dank Ed , Jetzt bekomme ich einen anderen Fehler über Pandas 'DataFrame' Objekt nicht aufrufbar ... Se meine Frage zu aktualisieren. – Excaliburst

+0

Ich bin mir nicht sicher, was Sie tun, aber das Problem hier ist, dass Sie eine Funktion definiert haben, die direkt auf dem df arbeitet, während Sie versuchen, gruppenweise zu arbeiten. Ich denke, Sie müssen schauen, was Sie wollen und was diese Funktion tut und überlegen, ob es das ist, was Sie wollen, weil dies der Grund ist, warum der Fehler ausgelöst wird – EdChum

+0

Ich muss eine neue Spalte "Trades" in meinen Pandas berechnen. Ich benutze die Funktion 'Trade_signal_calc'. Und um zu vermeiden, Nummern aus den verschiedenen Gruppen zu mischen, benutze ich pd groupby. Ich denke also, dass es nicht einfacher geht. Ich bin jedoch erstaunt, dass ich in jeder Gruppe keinen Zugang zu den fraglichen df-Spalten bekomme. Wie folgt: df ('MACD' [- 1]) (für die letzte Zeile), df ('MACD' [- 2]) (für vorletzte Zeile) ... Und die Funktion funktioniert für Gruppen, wie ich Spezifiere in den Parametern von f(). Die erste Par. Ist 'Gruppe' – Excaliburst