#python #dataframe
Вопрос:
Я ищу решение для получения строки при изменении определенного условия.
Вот пример моего фрейма данных.
ts fdw time_stamp 0 n [0, 0] 1635211605896 1 n [0, 0] 1635211606896 2 l [0, 0] 1635211607896 3 l [0, 0] 1635211608896 4 l [0, 0] 1635211609896 5 l [0, 0] 1635211609896 6 n [0, 0] 1635211609896
В приведенном выше фрейме данных я хочу извлечь строку при изменении имени столбца ts
, например, n
на l
или l
на n
.
Вот мой ожидаемый результат.
ts fdw time_stamp 1 n [0, 0] 1635211606896 2 l [0, 0] 1635211607896 5 l [0, 0] 1635211609896 6 n [0, 0] 1635211609896
Комментарии:
1. Какое, э-э, изменение условий заставило вас выбрать строки 1, 2, 5, 6?
2. @MarkMoretto, когда
ts
значение имени столбца отличается от предыдущего значения. Например, игнорируйте строку, когда ts имеет то же значение, что и предыдущая, и извлекайте строку, когда ts изменен.3.
df["time_stamp"] != df["time_stamp"].shift()
?4. @Jamjitul Разве индекс
0
и индекс1
не имеют одинаковое значение «ts»? Согласно вашему правилу, индекс0
должен быть сохранен, а1
его следует игнорировать. То же самое касается индекса5
. Все об индексе4
и5
одинаковы, если только я не вижу вещей, поэтому я не уверен, как это сработало.
Ответ №1:
import pandas import pdrle # Data df = pandas.DataFrame({"ts": ["n", "n", "l", "l", "l", "l", "n"]}) df["val"] = [1, 2, 3, 4, 5, 6, 7] # Get runs of consecutive lengths in ts rle = pdrle.encode(df.ts) grp = rle.index.repeat(rle.runs) # Get first and last row of each runs ans = ( df.groupby(grp) .apply(lambda x: x.iloc[[-1], :] if len(x) == 1 else x.iloc[[0, -1], :]) .droplevel(0) ) # If the first and last group have more than two rows, remove duplicates if rle.runs.iloc[0] gt; 1: ans.drop(ans.head(1).index, inplace=True) if rle.runs.iloc[-1] gt; 1: ans.drop(ans.tail(1).index, inplace=True) ans # ts val # 1 n 2 # 2 l 3 # 5 l 6 # 6 n 7