Este é meu DataFrame:
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]
}
)
A saída esperada é retornar um grupo x
com base na group
coluna:
group open close stop
0 x 100 105 104
1 x 150 150 104
2 x 200 200 104
3 x 160 160 104
Lógica:
Quero verificar se df.stop.iloc[0]
para cada grupo está entre df.open.iloc[0]
e df.close.iloc[0]
. E se estiver entre esses dois, quero retornar todo o grupo.
Esta é minha tentativa. Funciona, mas acho que há uma maneira melhor de fazer isso. Note que na if
cláusula, ambas as condições precisam ser verificadas.
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)
Você poderia
groupby.first
então construir uma máscara comisin
:Saída:
Intermediário
tmp
:com
groupby.filter
:grupos separados:
Saída:
sem groupby
Para este caso específico, você pode até pular
groupby
e substituí-lo pordrop_duplicates
:horários
Testado em ~ 7K linhas com grupos de 3 linhas
Você não precisa necessariamente
df.groupby
para isso:Saída:
Explicação
Series.between
ambos os lados e combine com um filtro que mantenha apenas a primeira linha por grupo (usando~
+df.duplicated
).m
) para selecionardf['group']
usandodf.loc
somente onde houver algumTrue
.Series.isin
applied todf['group']
.Claro, esse método seguirá o índice original, em vez de classificar os grupos. Mas no exemplo do OP, os dados já estão classificados.