У меня есть фрейм данных со столбцами:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'A': [False, True, False, False, False, False, True, True, False, True],
'B': [True, False, False, False, True, True, False, False, False, False ]
})
df
A B
0 False True
1 True False
2 False False
3 False False
4 False True
5 False True
6 True False
7 True False
8 False False
9 True False
Как идентифицировать и отметить первое вхождение, имеющее [True - False]
после встречи с парой значений [False - False]
? Каждую строку, удовлетворяющую этому условию, необходимо пометить в новом столбце.
В приведенном выше примере за [3 False False]
следует [6 True False]
, а за [8 False False]
следует [9 True False]
.
Это единственные допустимые решения в этом примере.
@mozway Мне следовало присмотреться к этому вопросу, спасибо.
Вы можете использовать:
# identify start of group
m1 = df.eq([False, False]).all(axis=1)
# condition
m2 = df.eq([True, False]).all(axis=1)
# form groups
group = m1.cumsum()
# keep only rows with valid condition and after a start of group
# get the first value per group
idx = m2[m2 & (group>0)].groupby(group).idxmax().tolist()
# variant
# idx = m2.index.to_series()[m2 & (group>0)].groupby(group).first().tolist()
# assign flag
df.loc[idx, 'flag'] = 'X'
Выход:
A B flag
0 False True NaN
1 True False NaN
2 False False NaN
3 False False NaN
4 False True NaN
5 False True NaN
6 True False X
7 True False NaN
8 False False NaN
9 True False X
Промежуточные продукты:
A B m1 m2 group flag
0 False True False False 0
1 True False False True 0
2 False False True False 1
3 False False True False 2
4 False True False False 2
5 False True False False 2
6 True False False True 2 X
7 True False False True 2
8 False False True False 3
9 True False False True 3 X
Вариант без groupby
:
# identify start of groups
m1 = df.eq([False, False]).all(axis=1)
# condition
m2 = (df.eq([True, False]).all(axis=1)
& m1.cummax()
)
# form groups
group = m1.cumsum()
idx = group[m2].drop_duplicates().index
# assign flag
df.loc[idx, 'flag'] = 'X'
Мне было интересно, можно ли здесь использовать FSM? С этими логическими переменными возможно только конечное число переходов между состояниями.
@prashanthmanohar, безусловно, есть и другие подходы, поскольку у вас есть DataFrame pandas, описанный выше подход кажется мне наиболее разумным.
@prashanthmanohar конечный автомат?
Да. ТФ, ФТ. FF, TT — это 4 возможных входа, которые могут идти в любом порядке. после получения входного сигнала FF, когда в конечном итоге будет получен TF, будет достигнуто ОКОНЧАТЕЛЬНОЕ СОСТОЯНИЕ автомата.
Конечно, но это означало бы использование цикла с флагами, не так ли? При достижении FF разрешаем собрать 1 ряд, при достижении TF собираем и возвращаемся в выключенное состояние. Вы можете использовать numbat.jit для такого кодирования. Примечание. Я добавил вариант своей логики без groupby
.
@MichaelButscher это будет работать только в том случае, если FF / TF последовательные, чего здесь, похоже, нет (например, 3->6)