Замена последующих N строк в столбце на 0 после нахождения значения по условию
Как сделать так, чтобы в последнем столбце после самой первой двойки, последующие N строк были заменены на 0? Скажем, 20 строк после первой найденной 2, если затем (после 20 нулей) будет еще 2, то еще последующие 20 строк = 0.
Пример данных (речь об 3-ем столбце конечно же):
11:55 1.10645224 0
11:56 1.10645224 0
11:57 1.10645224 1
11:58 1.10645224 1
11:59 1.10645224 1
12:00 1.10645224 1
12:01 1.10645224 2
12:02 1.10645224 1
12:03 1.10645224 1
12:04 1.10645224 1
12:05 1.10645224 1
12:06 1.10645224 1
12:07 1.10645224 1
12:08 1.10645224 2
12:09 1.10645224 1
12:10 1.10645224 1
12:11 1.10645224 2
12:12 1.10645224 1
12:13 1.10645224 1
12:14 1.10645224 1
12:15 1.10645224 1
12:16 1.10645224 1
Пример данных на dropmefiles.
Итог N = 10:
11:55 1.10645224 0
11:56 1.10645224 0
11:57 1.10645224 1
11:58 1.10645224 1
11:59 1.10645224 1
12:00 1.10645224 1
12:01 1.10645224 2
12:02 1.10645224 0
12:03 1.10645224 0
12:04 1.10645224 0
12:05 1.10645224 0
12:06 1.10645224 0
12:07 1.10645224 0
12:08 1.10645224 0
12:09 1.10645224 0
12:10 1.10645224 0
12:11 1.10645224 0
12:12 1.10645224 1
12:13 1.10645224 1
12:14 1.10645224 1
12:15 1.10645224 1
12:16 1.10645224 1
Ответы (1 шт):
Автор решения: MaxU
→ Ссылка
Алгоритм:
- находим индексы всех интересующих нас элементов
- устанавливаем правую границу интервала - первый индекс + N
- обнуляем N элементов между первым найденным индексом и правой границей
- цикл по найденным индексам, начиная со второго
- если текущий индекс <= правой границе (пред. индекс + N), то пропускаем его
- сдвигаем правую границу - текущий индекс + N
- обнуляем элементы между тек. индекс + 1 и правой границей
NOTE: цикл будет работать достаточно быстро, т.к. число итераций равно количеству искомых элементов (2 в вашем случае)
Код:
def f(col, N=10, search_for=2, fill_value=0):
s = col.reset_index(drop=True)
idx_list = s.loc[s==search_for].index
idx = idx_list[0]
s.loc[idx+1: idx+N] = fill_value
right_boundary = idx + N
for ii in idx_list[1:]:
# print(ii, ii+1, right_boundary)
if ii <= right_boundary:
continue
right_boundary = ii + N
s.loc[ii+1: right_boundary] = fill_value
return pd.Series(s.to_numpy(), index=col.index)
In [288]: d = pd.read_csv(r"C:\download\data_1.csv", index_col=0)
In [289]: idx = d.query("Threshold == 2").index
In [290]: idx
Out[290]: Int64Index([1457, 1464, 1467, 1995], dtype='int64')
In [291]: d["new"] = f(d["Threshold"], 10)
In [294]: d.loc[1457:1457+12]
Out[294]:
Date Time 72 Threshold new
1457 2015.07.06 12:01 1.106452 2 2
1458 2015.07.06 12:02 1.106452 1 0
1459 2015.07.06 12:03 1.106452 1 0
1460 2015.07.06 12:04 1.106452 1 0
1461 2015.07.06 12:05 1.106452 1 0
1462 2015.07.06 12:06 1.106452 1 0
1463 2015.07.06 12:07 1.106452 1 0
1464 2015.07.06 12:08 1.106452 2 0
1465 2015.07.06 12:09 1.106452 1 0
1466 2015.07.06 12:10 1.106452 1 0
1467 2015.07.06 12:11 1.106452 2 0
1468 2015.07.06 12:12 1.106452 1 1
1469 2015.07.06 12:13 1.106452 1 1