f()带functools.部分使用多个参数执行groupby

2024-04-19 01:15:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要决定一行股票报价是否符合某些标准。为此,我使用函数“Trade\u signal\u calc”来测试MACD(df中的一列)是否为正(first if)。然后,如果“MACD”从下面传递“MACDsig”(df的另一列)(第二个if),最后如果“MACD”从上面传递“MACDsig”(第三个if)。你知道吗

来自my df的这两个col'MACD'和'MACDsig'必须作为参数输入传递到my f()。结果列称为“Trade”,应该显示“Buy”、“Sell”或“NaN”。你知道吗

我只比较相同的股票,所以我使用pd.groupby公司用于此分组。它起作用了。你知道吗

但我一直在努力将多个输入参数(col)输入到f()中,因此终于在中找到了解决方案functools.部分这里提到: How does the functools partial work in Python?

它似乎工作/运行。不过,请参见我的代码和输出下面的问题

我的代码

import pandas as pd
import numpy as np
from io import StringIO
import functools

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', 'MACDperc'],inplace=True,axis=1)

#print('df to check numbering and cols. \n%s' %(df.iloc[0:4,0:6]))
#print('\ndf cols. 3-4 = MACD, MACDsig \n%s' %(df.iloc[0:4,2:4])) #rows, cols



def Trade_signal_calc(group, x, y):  # group
#def Trade_signal_calc(group):

    if df['MACD'].irow(-1) > 0: # MACD is pos. so trade (BUY/Sell)
        # BUY signals
        print('\n[MACD].irow(-1) > 0 PASSED 1st if\n Group: \n%s' %(group))
        # 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'
            print('\n(df[MACD].irow(-1) > df[MACDsig].irow(-1)) \
        & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) \n== PASSED 2nd if\n Group: \n%s' %(group))
            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'
            print('(df[MACD].irow(-1) < df[MACDsig].irow(-1)) \
        & (df[MACD].irow(-2) > df[MACDsig].irow(-2)) == PASSED 3rd (el)if\n MACD: \n%s, \nMACDsig: \n%s' %(x, y))
            return df
        else:   # No strong Buy or Sell signals
            print('No strong Buy or Sell signals')
            return df
    else:   # MACD is neg. so don't trade
        print('MACD is neg. so dont trade')
        return df



if __name__ == '__main__':

    # Multiindex Needed for my groupby to work properly ???
    df = df.set_index('Ticker', append=True)

    '''Testing functools.partial to manage the number of params for groupby to input 
    2 cols from df.'''

    fnc = functools.partial(Trade_signal_calc, x=df['MACD'], y=df['MACDsig'])
    df['Trade'] = df.groupby(level='Ticker').agg({'MACD': fnc, 'MACDsig': fnc})
#    df['Trade'] = df.groupby(level='Ticker').apply(lambda x: fcn())

    print ('\ndf with Buy & Sell signals & with multi-index (of Date and Ticker) \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 ('%s\ndf (summary from df - without multi-index) (Output)\n%s\n' %(75*'-',df))

输出(Stacktrace)

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AA        0.32
19-07-2016  AA        0.33
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AA        0.32
19-07-2016  AA        0.33
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAL       1.15
19-07-2016  AAL       1.32
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAL       1.15
19-07-2016  AAL       1.32
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAP       2.83
19-07-2016  AAP       2.71
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAP       2.83
19-07-2016  AAP       2.71
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAPL      0.50
19-07-2016  AAPL      0.67
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAPL      0.50
19-07-2016  AAPL      0.67
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.90
19-07-2016  ABBV      0.86
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.90
19-07-2016  ABBV      0.86
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABC       2.31
19-07-2016  ABC       2.38
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABC       2.31
19-07-2016  ABC       2.38
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABT      -1.05
19-07-2016  ABT       1.02
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABT      -1.05
19-07-2016  ABT       1.02
Name: MACD, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.21
19-07-2016  A         0.29
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.21
19-07-2016  A         0.29
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AA        0.10
19-07-2016  AA        0.15
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AA        0.10
19-07-2016  AA        0.15
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAL      -0.08
19-07-2016  AAL       0.19
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAL      -0.08
19-07-2016  AAL       0.19
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAP       2.72
19-07-2016  AAP       2.76
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAP       2.72
19-07-2016  AAP       2.76
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  AAPL     -0.16
19-07-2016  AAPL     -0.01
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  AAPL     -0.16
19-07-2016  AAPL     -0.01
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.71
19-07-2016  ABBV      0.78
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABBV      0.71
19-07-2016  ABBV      0.78
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABC       1.52
19-07-2016  ABC       1.70
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABC       1.52
19-07-2016  ABC       1.70
Name: MACDsig, dtype: float64

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  ABT       0.75
19-07-2016  ABT       0.84
Name: MACDsig, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  ABT       0.75
19-07-2016  ABT       0.84
Name: MACDsig, dtype: float64

df with Buy & Sell signals & with multi-index (of Date and Ticker) 
dfTrade shows trades from MACD & MACDsig comparison (summary from df) (Output)
---------------------------------------------------------------------------
Signals: 
Buy: (df(MACD[-1]) > df(MACDsig[-1])) & (df(MACD[-2]) < df(MACDsig[-2])) 
Sell: (df(MACD[-1]) < df(MACDsig[-1])) & (df(MACD[-2]) > df(MACDsig[-2])) 

                   Adj_Close  MACD  MACDsig Trade
Date       Ticker                                
18-07-2016 A           46.80  0.55     0.21   NaN
19-07-2016 A           46.98  0.60     0.29   NaN
18-07-2016 AA          10.92  0.32     0.10   NaN
19-07-2016 AA          10.63  0.33     0.15   NaN
18-07-2016 AAL         36.03  1.15    -0.08   NaN
19-07-2016 AAL         36.01  1.32     0.19   NaN
18-07-2016 AAP        164.40  2.83     2.72   NaN  At least this should be marked 'Buy'
19-07-2016 AAP        163.70  2.71     2.76   NaN
18-07-2016 AAPL        99.83  0.50    -0.16   NaN
19-07-2016 AAPL        99.87  0.67    -0.01   NaN
18-07-2016 ABBV        63.56  0.90     0.71   NaN
19-07-2016 ABBV        63.32  0.86     0.78   NaN
18-07-2016 ABC         86.03  2.31     1.52   NaN
19-07-2016 ABC         85.92  2.38     1.70   NaN
18-07-2016 ABT         42.09 -1.05     0.75   NaN
19-07-2016 ABT         41.80  1.02     0.84   NaN
---------------------------------------------------------------------------
df (summary from df - without multi-index) (Output)
           Ticker  Adj_Close  MACD  MACDsig Trade
Date                                             
18-07-2016      A      46.80  0.55     0.21   NaN
19-07-2016      A      46.98  0.60     0.29   NaN
18-07-2016     AA      10.92  0.32     0.10   NaN
19-07-2016     AA      10.63  0.33     0.15   NaN
18-07-2016    AAL      36.03  1.15    -0.08   NaN
19-07-2016    AAL      36.01  1.32     0.19   NaN
18-07-2016    AAP     164.40  2.83     2.72   NaN  At least this should be marked 'Buy'
19-07-2016    AAP     163.70  2.71     2.76   NaN
18-07-2016   AAPL      99.83  0.50    -0.16   NaN
19-07-2016   AAPL      99.87  0.67    -0.01   NaN
18-07-2016   ABBV      63.56  0.90     0.71   NaN
19-07-2016   ABBV      63.32  0.86     0.78   NaN
18-07-2016    ABC      86.03  2.31     1.52   NaN
19-07-2016    ABC      85.92  2.38     1.70   NaN
18-07-2016    ABT      42.09 -1.05     0.75   NaN
19-07-2016    ABT      41.80  1.02     0.84   NaN
  1. 我最后打印的两张df(一张有多个索引,一张没有),并没有显示AAP的股票行实际上应该标记为“买入”,而是简单地说NaN。。。这是错误的。。。你知道吗
  2. 我已经让if语句打印出显式的结果,所以我可以对if测试进行故障排除。根据my f(),这也不起作用,因为这些打印输出省略了第二个参数“MACDsig”col

看来我的groupby工作正常。同时使用我的fcn=。。。。运行,但在上面的打印输出中,它应该同时打印MACD和MACDsig cols。这不会发生,但只有在f()中指定为第一个输入参数的MACD会显示出来,为什么“MACDsig”列不能在这些输出中获得printet?你知道吗

这很可能也是我的if语句不能正常工作的原因。你知道吗

[MACD].irow(-1) > 0 PASSED 1st if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

(df[MACD].irow(-1) > df[MACDsig].irow(-1))         & (df[MACD].irow(-2) < df[MACDsig].irow(-2)) 
== PASSED 2nd if
 Group: 
Date        Ticker
18-07-2016  A         0.55
19-07-2016  A         0.60
Name: MACD, dtype: float64

Tags: namedfdateifgroupnanaaticker