Pandas- 基于列值查找行中的第一个出现位置

5

我有以下数据框:

 Row    Bid_price   Bid_volume  Ask_price   Ask_volume
 2      2999.0      786.7      -500.0       1403.2
 3      3000.0      786.7      -499.9       1407.2
 4      2950.0      787.3      -250.1       1407.2
---------------------
 56     125.1       2691       36.9         3113.1
 57     125         2691.1     37           3133.1
---------------------
 117    41.4        3029.7     2999         3835.7
 118    40.05       3029.7     3000         3835.7
---------------------
 123    39.4        3129.7     NaN          NaN
 124    36.1        3129.7     NaN          NaN
 125    36          3134.7     NaN          NaN

我需要取第一组 Bid_price 和 Bid_volume (2999.0 和 786.7) 和所有的 Ask_price 和 Ask_volume 进行比较。只要 Bid_volume < Ask_volume AND Bid_price > Ask_price,我就跳到下一组 Bid_price 和 Bid_volume 并再次与所有的 Ask_price 和 Ask_volume 进行比较。Bid_Price 递减,Bid_Volume 递增,Ask_Price 递增,Ask_Volume 递增。Bid_Price, Bid_Volume 长度相同,但 Ask_PriceAsk_Volume 较短。
输出应为第一个满足条件的实例,即 Bid_volume is > Ask_volume AND Bid_price < Ask_price。这在 line 124 中成立,与 line 56Ask_Price 和 Ask_Volume 相匹配。
期望的输出应为:
Row      Bid_price    Bid_volume  
124      36.1         3129.7

Row      Ask_price    Ask_volume
56       36.9         3113.1

我的问题是我只能逐行地进行条件评估。这样返回的是空值:

BidAsk = BidAsk[(BidAsk["Bid_volume"] > BidAsk["Ask_volume"]) & (BidAsk["Bid_price"] < BidAsk["Ask_price"])]
BidAsk[["Bid_price","Bid_volume"]]

这里会产生一个回溯错误:

BidAsk = BidAsk.where((BidAsk["Bid_volume"] > BidAsk["Ask_volume"]) & (BidAsk["Bid_Price"] < BidAsk["Ask_Price"]))
BidAsk[["Bid_price", "Bid_volume"]]

非常感激您的任何帮助。谢谢!


你的预期输出是什么? - Umar.H
我应该得到:买价:36.1,买量:3129.7。这是满足条件的第一对买价和买量。 - St_visual
2个回答

0
第一种方法返回空值,因为两个条件始终为假,你必须反转比较符号。
BidAsk = BidAsk[(BidAsk["Bid_volume"] < BidAsk["Ask_volume"]) & (BidAsk["Bid_price"] > BidAsk["Ask_price"])]

谢谢Pica,条件在时间序列中进一步满足,我只发布了前5行。Bid_Price正在下降,Bid_Volume正在增加,Ask_Price正在增加,Ask_Volume正在增加。如果我可以上传.csv文件,可能更容易理解? - St_visual

0

希望我理解你的意思是,这个脚本将找到满足条件 Bid_volume is > Ask_volume AND Bid_price < Ask_priceBid_priceBid_volume

如果我有这个数据框:

   Bid_price  Bid_volume  Ask_price  Ask_volume
0     2999.0       786.7     -500.0      1403.2
1     3000.0       786.7     -499.9      1407.2
2     2950.0       787.3     -250.1      1407.2
3     2500.0       792.8     -250.0      1593.2
4     2000.0       798.9     -200.1      1593.2
5     1400.0      2000.0     1200.0      1600.0
6       36.1      3129.7        NaN         NaN

然后:

import pandas as pd
from io import StringIO

txt = '''Bid_price   Bid_volume  Ask_price   Ask_volume
2999.0      786.7      -500.0       1403.2
3000.0      786.7      -499.9       1407.2
2950.0      787.3      -250.1       1407.2
2500.0      792.8      -250.0       1593.2
2000.0      798.9      -200.1       1593.2
1400.0     2000.0      1200.0       1600.0
  36.1     3129.7             '''

df = pd.read_fwf(StringIO(txt))

max_price = df.Ask_price.max()
max_volume = df.Ask_volume.max()

mask = pd.concat([df.Bid_price < max_price, df.Bid_volume > max_volume], axis=1).all(axis=1)

print( df.loc[mask, ['Bid_price', 'Bid_volume']].head(1) )

输出:

   Bid_price  Bid_volume
6       36.1      3129.7

编辑(根据更新后的问题):

import pandas as pd
from io import StringIO

txt = ''' Row    Bid_price   Bid_volume  Ask_price   Ask_volume
 2      2999.0      786.7      -500.0       1403.2
 3      3000.0      786.7      -499.9       1407.2
 4      2950.0      787.3      -250.1       1407.2
 56     125.1       2691       36.9         3113.1
 57     125         2691.1     37           3133.1
 117    41.4        3029.7     2999         3835.7
 118    40.05       3029.7     3000         3835.7
 123    39.4        3129.7     NaN          NaN
 124    36.1        3129.7     NaN          NaN
 125    36          3134.7     NaN          NaN'''

df = pd.read_fwf(StringIO(txt))

def get_indexes(df):
    for idx1, bid_price, bid_volume in zip(df.index, df.Bid_price, df.Bid_volume):
        for idx2, ask_price, ask_volume in zip(df.index, df.Ask_price, df.Ask_volume):
            if bid_volume > ask_volume and bid_price < ask_price:
                return idx1, idx2, bid_price, bid_volume, ask_price, ask_volume

print(df)
print()

result = get_indexes(df)
if result:
    print('Bid Price   =', result[2])
    print('Bid Volume  =', result[3])
    print('Ask Price   =', result[4])
    print('Ask Volume  =', result[5])
    print('Index bid   =', result[0])
    print('Index ask   =', result[1])

输出:

   Row  Bid_price  Bid_volume  Ask_price  Ask_volume
0    2    2999.00       786.7     -500.0      1403.2
1    3    3000.00       786.7     -499.9      1407.2
2    4    2950.00       787.3     -250.1      1407.2
3   56     125.10      2691.0       36.9      3113.1
4   57     125.00      2691.1       37.0      3133.1
5  117      41.40      3029.7     2999.0      3835.7
6  118      40.05      3029.7     3000.0      3835.7
7  123      39.40      3129.7        NaN         NaN
8  124      36.10      3129.7        NaN         NaN
9  125      36.00      3134.7        NaN         NaN

Bid Price   = 36.1
Bid Volume  = 3129.7
Ask Price   = 36.9
Ask Volume  = 3113.1
Index bid   = 8
Index ask   = 3

谢谢Andrej,我认为这是朝着正确方向的一步,但是我遇到了错误“'DataFrame' object has no attribute 'concat'”。当我尝试使用.idxmax()时,我也遇到了同样的错误。总是数据框没有这样的属性...我希望在正文中更好地解释了问题。最好的。 - St_visual
@St_visual 我更新了我的回答。看起来你在 pd 中存储了一个数据框。我使用 pd 作为 pandas 模块(请参见我的回答)。 - Andrej Kesely
Concat 工作了!就快完成了,我得到的结果是:行160,买价24.5,买量3982.7。但是条件已经在行124中满足了,因为我已经在正文中写过了。我认为这是因为我们正在与 df.Ask_price.max()df.Ask_volume.max() 进行比较,但我们应该逐行比较每对 Ask_priceAsk_volume,以找到第一个满足条件的实例。非常感谢! - St_visual
@St_visual 我更新了我的答案。根据更新后的问题,解决方案似乎很简单,只需使用循环即可。 - Andrej Kesely
1
非常感谢Andrej,这正是我在寻找的!我是Python的新手,我无法想出这种解决方案。在VBA中,它是一个非常类似的循环。再次感谢!最好的祝福。 - St_visual

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接