首页 > 解决方案 > 在 pandas 数据框列中找到匹配后的行数

问题描述

我有以下数据框和预期的输出,我在其中搜索列中的Truebalance。一旦找到,我使用balPrice该行的列值并将其与endPrice寻找第一个实例的列进行比较,其中第一个实例endPrice低于balPrice并计算该行的balance == True行数和找到的较低值行的第一个实例。如果没有找到更低的值,则将行计数设置为 0。

balance balPrice    endPrice
0   False   5.34    5.34
1   False   5.34    5.34
2   False   5.34    5.34
3   False   5.34    5.27
4   False   5.44    5.25
5   False   5.28    5.12
6   True    5.31    5.2
7   False   5.44    5.35
8   False   5.485   5.44
9   False   5.525   5.5
10  False   5.53    5.53
11  False   5.58    5.51
12  False   5.65    5.52
13  False   5.3     5.3
14  False   5.58    5.54
15  False   5.64    5.55
16  True    5.69    5.65
17  False   5.69    5.59
18  False   5.7     5.62
19  False   5.81    5.77
20  False   5.65    5.73
21  False   5.65    5.86
22  True    6.00    5.89
23  False   5.65    5.85
24  False   5.65    5.83
25  False   5.9     5.88

这是我尝试过的,看起来很复杂。正在寻找更好的解决方案。

df_filtered = df[df.balance == True]
idx = []
for i in df_filtered.index:
    pos = np.where(df.endPrice[i+1:] <= df.balPrice[i])[0]
    if pos.size > 0:
        idx.append(pos[0]+1)
    else:
        idx.append(0)

df_filtered['numrows'] = idx     

预期输出:

balance balPrice    endPrice    numrows
True    5.31        5.2           7
True    5.69        5.65          1
True    6.00        5.89          1

标签: pythonpandasdataframe

解决方案


您可以使用然后将这些组从一个balance == True到下一个行分组:groupby(df.balance.cumsum())apply(numrows)

def numrows(group):
    index = (group.endPrice.iloc[1:] <= group.balPrice.iloc[0]).idxmax()
    result = index - group.index[0]
    return result

numrows = df.groupby(df.balance.cumsum()).apply(numrows)[1:]
df['numrows'] = numrows.set_axis(df[df.balance].index)
df['numrows'] = df.numrows.fillna(0).astype(int)

这给出了除行numrows之外的 0balance == True列:

df.tail()

#    balance  balPrice  endPrice  numrows
# ...
# 21   False      5.65      5.86        0
# 22    True      6.00      5.89        1
# 23   False      5.65      5.85        0
# 24   False      5.65      5.83        0
# 25   False      5.90      5.88        0

所以最后你可以这样做:

df[df.balance]

#    balance  balPrice  endPrice  numrows
#  6    True      5.31      5.20        7
# 16    True      5.69      5.65        1
# 22    True      6.00      5.89        1

推荐阅读