如何比较 numpy ndarray 的所有值和数据框的特定列以提取该数据框另一列的相应值

How to compare all values of numpy ndarray and a particular column of data frame to extract corresponding values of another column of that data frame

import requests
import pandas as pd
import numpy
def get_token(instrument):
    response = requests.get("https://api.kite.trade/instruments")
    var1 = response.content.decode('ISO-8859-1')
    df = pd.DataFrame([x.split(',') for x in var1.split('\n')])
    df =df.rename(columns=df.iloc[0]).drop(df.index[0])
    mask = df['segment'].isin(['NFO-FUT', 'NFO-OPT'])
    df_filtered = df[mask]
    if (instrument.lower() == "future"):
        df = df_filtered.loc[df_filtered['segment'] == 'NFO-FUT']
    else:
        df = df_filtered.loc[df_filtered['segment'] == 'NFO-OPT']
    df = df.drop(['tick_size', 'last_price'], axis = 1)
    return df.replace('"','', regex=True)

df = get_token("Option")
# print(df)
def get_bhavcopy(date):
    date = date.replace("-","")
    try:
        payload=pd.read_csv("https://archives.nseindia.com/products/content/sec_bhavdata_full_"+date+".csv", skipinitialspace = True)
    except Exception as e:
        print(e)
    return payload
pd.set_option('max_column', None)
price_data= get_bhavcopy("25-06-2021")
mask = price_data['SERIES'].isin(['EQ'])
price_data = price_data[mask]
df_np = df['name'].unique()
data = pd.DataFrame(columns=['name','close'])

我正在尝试获得 ATM 罢工,以及 5 次高于和低于 ATM 的罢工。

我在这里做的是

  1. 从 NSE 获取每个交易品种的价格
  2. 获取所有F&O的罢工名单

并打算通过获取最接近每个交易品种最后收盘价的行使价来找到 ATM 行使价。

因此我需要比较 df_np(np 数组)中的每个值和 price_data 中的“SYMBOL”列 (dataFrame) 获取最后价格,以便我可以使用它从 df

中找到 ATM 罢工

我不知道该怎么做!!或者如果有任何更好的方法可以实现我的目标,即 在特定日期为某个代码找到 10 个高于和低于 ATM 价格的行使价。

一起获取代码、最后价格和行使价

首先,让我们为每个交易品种获取一个包含最后价格(收盘价)的适当数据框:将 df_np 变成它自己的数据框,然后与 price_data 合并并提取相关列:

last_px = pd.merge(pd.DataFrame({'SYMBOL': df_np}), price_data)[['SYMBOL', 'LAST_PRICE']]

df 数据框上,我们按名称对行使价进行分组,并按列表进行汇总,这样我们就可以构建一个数据框,其中每个名称都与一个行使价列表相关联。此外,将 'name' 更改为 'SYMBOL' 以准备再次合并:

strikes = pd.DataFrame(df.groupby('name')['strike'].agg(list)).reset_index()
strikes.columns = ['SYMBOL', 'strike']

现在将最后价格和行使价合并在一起:

df3 = pd.merge(last_px, strikes)

现在我们有以下数据框:

In [26]: df3
Out[26]: 
         SYMBOL  LAST_PRICE                                             strike
0      AARTIIND      862.10  [1000, 1000, 1010, 1010, 1020, 1020, 1030, 103...
1         ABFRL      222.80  [165, 165, 170, 170, 175, 175, 180, 180, 185, ...
2           ACC     2044.90  [1160, 1160, 1180, 1180, 1200, 1200, 1220, 122...
3      ADANIENT     1516.00  [1000, 1000, 1020, 1020, 1040, 1040, 1060, 106...
4    ADANIPORTS      711.00  [1000, 1000, 1010, 1010, 1020, 1020, 1030, 103...
..          ...         ...                                                ...
155         UPL      803.55  [410, 410, 420, 420, 430, 430, 440, 440, 450, ...
156        VEDL      262.55  [165, 165, 170, 170, 175, 175, 180, 180, 185, ...
157      VOLTAS     1030.00  [1000, 1000, 1020, 1020, 1040, 1040, 1060, 106...
158       WIPRO      546.90  [320, 320, 325, 325, 330, 330, 335, 335, 340, ...
159        ZEEL      218.00  [130, 130, 135, 135, 140, 140, 145, 145, 150, ...

[160 rows x 3 columns]

找出 ATM 价格附近的行使价

现在我们要在每一行上应用一个函数,使用最后的价格和行使价列表来确定 ATM 价格和上方和下方的 5 个行使价。该函数将罢工列表转换为它自己的数据框(具有浮点值),然后添加一个列来计算与最后价格的差异,idxmin 函数将告诉我们差异最小的位置,即我们在哪里接近ATM价格。使用 iloc(因为我们重置了索引)很容易找到 +/- 5 个索引,所以我们 return 将这些值作为列表。

函数定义如下:

def around_atm(last_prc, strike_list):
    xdf = pd.DataFrame({'strikes': strike_list}).reset_index(drop=True)
    xdf['strikes'] = xdf['strikes'].astype(float)
    xdf['abs_delta'] = abs(last_prc - xdf['strikes'])
    imin = xdf['abs_delta'].idxmin()
    return xdf.iloc[imin-5:imin+5]['strikes'].tolist()

最后,让我们应用这个函数,将结果放在一个新列中:

df3['above_below'] = df3.apply(lambda x: around_atm(x['LAST_PRICE'], x['strike']), axis=1)

above_below 列现在包含高于和低于 ATM 价格的 5 行使价:

In [30]: df3
Out[30]: 
         SYMBOL  LAST_PRICE  \
0      AARTIIND      862.10   
1         ABFRL      222.80   
2           ACC     2044.90   
3      ADANIENT     1516.00   
4    ADANIPORTS      711.00   
..          ...         ...   
155         UPL      803.55   
156        VEDL      262.55   
157      VOLTAS     1030.00   
158       WIPRO      546.90   
159        ZEEL      218.00   

                                                strike  \
0    [1000, 1000, 1010, 1010, 1020, 1020, 1030, 103...   
1    [165, 165, 170, 170, 175, 175, 180, 180, 185, ...   
2    [1160, 1160, 1180, 1180, 1200, 1200, 1220, 122...   
3    [1000, 1000, 1020, 1020, 1040, 1040, 1060, 106...   
4    [1000, 1000, 1010, 1010, 1020, 1020, 1030, 103...   
..                                                 ...   
155  [410, 410, 420, 420, 430, 430, 440, 440, 450, ...   
156  [165, 165, 170, 170, 175, 175, 180, 180, 185, ...   
157  [1000, 1000, 1020, 1020, 1040, 1040, 1060, 106...   
158  [320, 320, 325, 325, 330, 330, 335, 335, 340, ...   
159  [130, 130, 135, 135, 140, 140, 145, 145, 150, ...   

                                           above_below  
0    [830.0, 840.0, 840.0, 850.0, 850.0, 860.0, 860...  
1    [210.0, 215.0, 215.0, 220.0, 220.0, 225.0, 225...  
2    [1980.0, 2000.0, 2000.0, 2020.0, 2020.0, 2040....  
3    [1460.0, 1480.0, 1480.0, 1500.0, 1500.0, 1520....  
4    [680.0, 690.0, 690.0, 700.0, 700.0, 710.0, 710...  
..                                                 ...  
155  [770.0, 780.0, 780.0, 790.0, 790.0, 800.0, 800...  
156  [250.0, 255.0, 255.0, 260.0, 260.0, 265.0, 265...  
157                                                 []  
158  [530.0, 535.0, 535.0, 540.0, 540.0, 545.0, 545...  
159  [205.0, 210.0, 210.0, 215.0, 215.0, 220.0, 220...  

[160 rows x 4 columns]