这是我的数据框:
import pandas as pd
df = pd.DataFrame(
{
'group': list('xxxxyyy'),
'open': [100, 150, 200, 160, 300, 150, 170],
'close': [105, 150, 200, 160, 350, 150, 170],
'stop': [104, 104, 104, 104, 400, 400, 400]
}
)
预期输出是x
根据group
列返回的组:
group open close stop
0 x 100 105 104
1 x 150 150 104
2 x 200 200 104
3 x 160 160 104
逻辑:
我想检查df.stop.iloc[0]
每个组是否在df.open.iloc[0]
和之间df.close.iloc[0]
。如果在这两者之间,我想返回整个组。
这是我的尝试。它有效,但我认为有更好的方法。请注意,在if
子句中,需要检查两个条件。
def func(df):
s = df.stop.iloc[0]
o = df.open.iloc[0]
c = df.close.iloc[0]
if (o <= s <= c) or (c <= s <= o):
return df
out = df.groupby('group').apply(func).reset_index(drop=True)
然后,你可以
groupby.first
用以下方法制作一个面具isin
:输出:
中间的
tmp
:和
groupby.filter
:独立组:
输出:
没有 groupby
对于这种特殊情况,您甚至可以跳过
groupby
并将其替换为drop_duplicates
:时间安排
测试了约 7K 行,每组 3 行
您不一定需
df.groupby
要这样做:输出:
解释
Series.between
两侧并结合仅保留每组第一行的过滤器(使用~
+df.duplicated
)。m
选择。df['group']
df.loc
True
Series.isin
应用于df['group']
。当然,这种方法会遵循原始索引,而不是对组进行排序。但在OP的例子中,数据已经排序了。