【问题标题】: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如何比较numpy ndarray的所有值和数据框的特定列以提取该数据框另一列的对应值
【发布时间】:2021-06-27 10:02:33
【问题描述】:
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 罢工,以及 ATM 上方和下方的 5 次罢工。

我在这里做的是

  1. 从 NSE 获取每个符号的价格
  2. 获取所有 F&O 的罢工名单

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

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

找到 ATM 罢工

我不知道该怎么做!或者如果有任何更好的方法可以实现我的目标,即在特定日期为某个交易品种找到 ATM 价格上下 10 次罢工。

【问题讨论】:

  • 符号在price_data 数据框中不是唯一的,如何选择给定符号的最后价格?
  • 符号是唯一的,因为我是从 NSE 网站本身获取的,并且在给定日期内不能有两个同名的符号。
  • 我运行了你的代码,在很多情况下,相同的 SYMBOL 在 2021 年 6 月 25 日多次出现,但 SERIES 不同。尝试运行price_data['SYMBOL'].value_counts()
  • 感谢您指出,我错过了它,因为我只是在 excel 中执行了“删除重复项”,它显示“未找到重复项”(可能是我选择了错误的列)。我现在通过根据我的要求过滤它来删除重复项。 @joao

标签: python-3.x pandas dataframe numpy-ndarray


【解决方案1】:

获取交易品种、最后价格和行权价

首先,让我们获得一个包含每个交易品种最后价格(收盘价)的适当数据框:将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 函数将告诉我们差异最小的位置,即我们离哪里更近自动取款机价格。使用 iloc(并且因为我们重置了索引)很容易找到 +/- 5 个索引,因此我们将这些值作为列表返回。

这是函数定义:

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]

【讨论】:

  • 非常感谢所有的辛勤工作。你能告诉我为什么某些符号的值没有出现在“above_below”列中吗?
  • 它看起来像一个边界条件,当 ATM 太接近罢工的最小值或最大值,并且一侧的罢工少于 5 次。也许将imin-5 替换为max(0, imin-5),并为imin+5 替换类似的东西?
  • 谢谢。达到目的。在为 ATM 价格范围(在 above_below 列中)找到相应的工具代币时,我又遇到了一个问题。你能帮我解决这个问题吗?我只是从前天开始就被困在这里。我尝试的是返回交易符号以及在 ATM 上方找到的执行价格。但是我必须再次将它们与不同的df匹配才能找到insturment_tokens,这似乎需要很多处理。有没有其他方法可以获取上述罢工的instrument_tokens?
  • 我想你的意思是 df 中的 instrument_token 列?我会添加一个couple 列来存储令牌和罢工之间的关联(可能是df['couple'] = df['instrument_token'].str.cat(df['strike'], sep=' '),但我确信还有其他方法),然后使用该couple 列而不是strike。然后修改around_atm 函数以说明罢工现在在一对夫妇内部,因此above_below 中是一对夫妇的列(或者您可以将夫妇分开)。您最终会得到一个包含符号、最后、标记和罢工的行。
猜你喜欢
  • 1970-01-01
  • 2020-08-13
  • 2016-02-11
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2022-08-18
  • 1970-01-01
  • 2020-02-22
相关资源
最近更新 更多