У меня есть следующий фрейм данных:
midPrice Change % Spike New Oilprice
92.20000 0.00 0 92.043405
92.26454 0.07 0 92.049689
91.96950 -0.32 0 91.979751
91.73958 -0.25 0 91.844369
91.78985 0.05 0 91.724690
91.41000 -0.41 0 91.568880
91.18148 -0.25 0 91.690812
91.24257 0.07 0 91.858391
90.95352 -0.32 0 92.016806
93.24000 2.51 1 92.139872
93.31013 0.08 0 92.321622
93.00690 -0.32 0 92.542687
92.77438 -0.25 0 92.727070
92.86400 0.10 0 92.949655
и всякий раз, когда у меня есть пик (1) в столбце, я хочу заменить 5 строк после пика (включая) новыми ценами на нефть. Остальные ряды сохраняются как есть.
Любые идеи, как это решить? Я попробовал код на основе следующего:
def spike(i):
for i in df['Spike']:
if i.loc == 1:
df['midPrice'].replace(df['New Oilprice'][i:5])`
К сожалению, это не работает, и я не так силен в пандах. Я также попытался сопоставить функцию с фреймом данных, но это тоже не сработало. Буду признателен за любую помощь
Даже если лучше, это все равно скриншот. Вы действительно можете просто скопировать содержимое фрейма данных в виде текста и вставить его в вопрос внутри блока кода. Также глянь сюда
Что должно произойти, если в течение пяти пяти дней произойдет два всплеска? Заменяет ли первый выброс следующие пять строк, но затем второй выброс использует 1/свое старое значение или 2/свое новое, замененное значение для следующих пяти рядов? Или что-то совсем другое?
Если вы используете вывод f"DataFrame({df.to_dict()})
(без окружающих кавычек и аккуратно отформатированный с разрывами строк), мы можем легко скопировать и вставить пример фрейма данных.
Предполагая, что df отсортирован по времени в порядке возрастания (как я видел в истории редактирования вашего вопроса, у вас есть столбец времени), вы можете использовать такую маску:
mask = df['Spike'].eq(1).where(df['Spike'].eq(1)).fillna(method='ffill', limit=4).fillna(False)
df.loc[mask, 'midPrice'] = df['New Oilprice']
print(df)
midPrice Change % Spike New Oilprice
0 92.200000 0.00 0 92.043405
1 92.264540 0.07 0 92.049689
2 91.969500 -0.32 0 91.979751
3 91.739580 -0.25 0 91.844369
4 91.789850 0.05 0 91.724690
5 91.410000 -0.41 0 91.568880
6 91.181480 -0.25 0 91.690812
7 91.242570 0.07 0 91.858391
8 90.953520 -0.32 0 92.016806
9 92.139872 2.51 1 92.139872
10 92.321622 0.08 0 92.321622
11 92.542687 -0.32 0 92.542687
12 92.727070 -0.25 0 92.727070
13 92.949655 0.10 0 92.949655
Вы можете настроить маску с помощью другого fillna
:
mask = df['Spike'].eq(1).where(df['Spike'].eq(1)).fillna(method='bfill', limit=2).fillna(method='ffill', limit=3).fillna(False)
df.loc[mask, 'midPrice'] = df['New Oilprice']
print(df)
midPrice Change % Spike New Oilprice
0 92.200000 0.00 0 92.043405
1 92.264540 0.07 0 92.049689
2 91.969500 -0.32 0 91.979751
3 91.739580 -0.25 0 91.844369
4 91.789850 0.05 0 91.724690
5 91.410000 -0.41 0 91.568880
6 91.181480 -0.25 0 91.690812
7 91.858391 0.07 0 91.858391
8 92.016806 -0.32 0 92.016806
9 92.139872 2.51 1 92.139872
10 92.321622 0.08 0 92.321622
11 92.542687 -0.32 0 92.542687
12 92.727070 -0.25 0 92.727070
13 92.949655 0.10 0 92.949655
Отлично спасибо! Это работает. Могу ли я также настроить его, чтобы сделать его на 2 ряда раньше и на 3 ряда позже после шипа? Буду ли я делать это с индексацией?
@ Элен, ты имеешь в виду вот так? 2 ряда + ряд с шипами + 3 ряда после? всего 6 рядов включая шип?
@Helene, проверьте мое редактирование, чтобы убедиться, что вы это имели в виду.
Да, большое спасибо. Вы избавили меня от ручной работы :)
@Элен, без проблем! Ах, не забудьте отсортировать df по времени (по возрастанию). Я также добавлю это к своему ответу
Пожалуйста, опубликуйте пример фрейма данных в виде текста (и ожидаемого результата) вместо снимка экрана.