Home > Blockchain >  IndexingError: Too many indexers with Dataframe.loc
IndexingError: Too many indexers with Dataframe.loc

Time:08-29

I got this error while I tried to make telegram alarm bot using FinanceDataReader

Here is the code:

code = 'KQ11'
df = fdr.DataReader('KR11', '2022-08').reset_index()
df['close_sma3d'] = df['Close'].rolling(3).mean()
df['close_sma5d'] = df['Close'].rolling(5).mean()
df['close_sma10d'] = df['Close'].rolling(10).mean()


print('3,5,10 SMA breakout Signal')

Three_days = 3
Five_days = 5
Ten_days = 10

for i in date_i:

# we cannot calculate the first day and the last day
if i < 1 or i > len(date_list) - Ten_days:
    continue
    
prev_date = date_list[i-1]
now_date = date_list[i]

prev_price = df['Close'].loc[code, prev_date]
now_price = df['Close'].loc[code, now_date]

prev_sma3d = df['close_sma3d'].loc[code, prev_date]
now_sma3d = df['close_sma3d'].loc[code, now_date]

prev_sma5d = df['close_sma5d'].loc[code, prev_date]
now_sma5d = df['close_sma5d'].loc[code, now_date]

prev_sma10d = df['close_sma10d'].loc[code, prev_date]
now_sma10d = df['close_sma10d'].loc[code, now_date]

# 어제는 이평선 밑, 당일은 이평선 위
if now_price > now_sma3d:
    print(f" - {now_date} Signal 발생! now_price {now_price} 3일이동평균 {now_sma3d}")
    
elif now_price > now_sma5d:
    print(f" - {now_date} Signal 발생! now_price {now_price} 5일이동평균 {now_sma5d}")

elif now_price > now_sma10d:
    print(f" - {now_date} Signal 발생! now_price {now_price} 10일이동평균 {now_sma10d}")

And here is the code where the error occured:

prev_price = df['Close'].loc[code, prev_date]

Dataframe looks like this:

    Date    Close   close_sma3d close_sma5d close_sma10d

9   2022-08-12  831.63  828.016667  829.712 823.267
10  2022-08-16  834.74  832.840000  830.488 825.980
11  2022-08-17  827.42  831.263333  829.242 828.288
12  2022-08-18  826.06  829.406667  830.400 829.358
13  2022-08-19  814.17  822.550000  826.804 828.259
14  2022-08-22  795.87  812.033333  819.652 824.682
15  2022-08-23  783.42  797.820000  809.388 819.938
16  2022-08-24  793.14  790.810000  802.532 815.887
17  2022-08-25  807.37  794.643333  798.794 814.597
18  2022-08-26  802.45  800.986667  796.450 811.627

When I print(prev_date, now_date):

2022-08-01 00:00:00
2022-08-02 00:00:00

it seems really weird cause it's not a form of Multiindex to me

I found that it has no columns even though it's DataFrame. When I df['Close'].shape it shows: (19,)

Any help would be appreicated.

CodePudding user response:

You use .loc with wrong values. It rather need .loc[ row_indexes, columns_names ] but you use some strange code and value prev_date

To select some date it would need

df.loc[ df["Date"] == prev_date, 'Close']

But you don't need it in some situations.


To find all "Close" > "close_sma3d" you can do

alert_three_days = df[ df['Close'] > df['close_sma3d'] ]

and later iterate this dataframe

for index, row in alert_three_days.iterrows():
    print(f" - {row['Date']} Signal 발생! now_price {row['Close']} 3일이동평균 {row['close_sma3d']}")

or use apply() for this

def display(row):
    print(f" - {row['Date']} Signal 발생! now_price {row['Close']} 3일이동평균 {row['close_sma3d']}")

alert_three_days.apply(display, axis=1)

If you want to compare with previous price then you can use .shift(1)

df['Previous Close'] = df['Close'].shift(1)

and later compare

lower_close = df[ df['Previous Close'] > df['Close'] ]

and display only selected rows

print(lower_close[['Previous Close', 'Close']])

BTW:

When you get single column df['Close'] then it gives you pandas.Series (which don't have columns) and .shape shows only number of rows in this Series


Minimal working code for tests:

import FinanceDataReader as fdr

df = fdr.DataReader('KQ11', '2022-08').reset_index()

df['close_sma3d']  = df['Close'].rolling(3).mean()
df['close_sma5d']  = df['Close'].rolling(5).mean()
df['close_sma10d'] = df['Close'].rolling(10).mean()

print('\n--- Close for 2022-08-03 ---\n')

print(df.loc[ df['Date'] == '2022-08-03', 'Close'])

print('\n--- Previous Close > Close ---\n')

df['Previous Close'] = df['Close'].shift(1)
#df['Previous Date']  = df['Date'].shift(1)

lower_close = df[ df['Previous Close'] > df['Close'] ]
print(lower_close[['Previous Close', 'Close', 'Date']])

print('\n--- alert_three_days ---\n')

alert_three_days = df[ df['Close'] > df['close_sma3d'] ]
#print(alert_three_days)

#def display(row):
#    print(f" - {row['Date']} Signal 발생! now_price {row['Close']} 3일이동평균 {row['close_sma3d']}")
#alert_three_days.apply(display, axis=1)

for index, row in alert_three_days.iterrows():
    print(f" - {row['Date']} Signal 발생! now_price {row['Close']} 3일이동평균 {row['close_sma3d']}")

Results:

--- Close for 2022-08-03 ---

2    815.36
Name: Close, dtype: float64

--- Previous Close > Close ---

    Previous Close   Close       Date
1           807.61  804.34 2022-08-02
5           831.64  830.86 2022-08-08
7           833.65  820.27 2022-08-10
9           832.15  831.63 2022-08-12
11          834.74  827.42 2022-08-17
12          827.42  826.06 2022-08-18
13          826.06  814.17 2022-08-19
14          814.17  795.87 2022-08-22
15          795.87  783.42 2022-08-23
18          807.37  802.45 2022-08-26

--- alert_three_days ---

 - 2022-08-03 00:00:00 Signal 발생! now_price 815.36 3일이동평균 809.1033333333334
 - 2022-08-04 00:00:00 Signal 발생! now_price 825.16 3일이동평균 814.9533333333333
 - 2022-08-05 00:00:00 Signal 발생! now_price 831.64 3일이동평균 824.0533333333333
 - 2022-08-08 00:00:00 Signal 발생! now_price 830.86 3일이동평균 829.2199999999999
 - 2022-08-09 00:00:00 Signal 발생! now_price 833.65 3일이동평균 832.0500000000001
 - 2022-08-11 00:00:00 Signal 발생! now_price 832.15 3일이동평균 828.6899999999999
 - 2022-08-12 00:00:00 Signal 발생! now_price 831.63 3일이동평균 828.0166666666665
 - 2022-08-16 00:00:00 Signal 발생! now_price 834.74 3일이동평균 832.84
 - 2022-08-24 00:00:00 Signal 발생! now_price 793.14 3일이동평균 790.81
 - 2022-08-25 00:00:00 Signal 발생! now_price 807.37 3일이동평균 794.6433333333333
 - 2022-08-26 00:00:00 Signal 발생! now_price 802.45 3일이동평균 800.9866666666667
  • Related