Вы можете преобразовать свой индекс в timdelta
или строки перед сравнением:
# timedelta option, vectorised & efficient
mask_bool = (df.index - df.index.normalize()) == '09:15:00'
# string alternative, inefficient
mask_bool = df.index.strftime('%H:%M') == '09:15'
Затем назначьте через loc
или mask
:
# Option 1: assign conditionally via loc
df.loc[mask_bool, 'Open'] = df['Close'].shift(1)
# Option 2: mask with pd.Series.mask
df['Open'] = df['Open'].mask(mask_bool, df['Close'].shift(1))
Результат:
print(df)
Close High Open Low
Date_Time
2018-11-22 07:15:00 321.30 321.30 321.30 321.30
2018-11-22 09:15:00 324.50 326.90 321.30 320.00
2018-11-22 11:15:00 323.20 324.85 324.60 322.20
2018-11-22 13:15:00 319.90 324.35 323.20 319.50
2018-11-22 15:15:00 320.00 320.35 319.85 319.15
2018-11-26 07:15:00 324.90 324.90 324.90 324.90
2018-11-26 09:15:00 311.35 324.40 324.90 309.60
Сравнительный анализ производительности
Для больших фреймов данных векторизованная версия timedelta
должна быть эффективной, но учтите, что это будет зависеть от системы и настройки:
# Python 3.6.5, Pandas 0.23, NumPy 1.14.3
import pandas as pd
from datetime import time
df = pd.DataFrame.from_dict({'Date_Time': ['2018-11-22 07:15:00', '2018-11-22 09:15:00',
'2018-11-22 11:15:00', '2018-11-22 13:15:00',
'2018-11-22 15:15:00', '2018-11-26 07:15:00',
'2018-11-26 09:15:00'],
'Close': [321.3, 324.5, 323.2, 319.9, 320.0, 324.9, 311.35],
'High': [321.3, 326.9, 324.85, 324.35, 320.35, 324.9, 324.4],
'Open': [321.3, 321.3, 324.6, 323.2, 319.85, 324.9, 324.9],
'Low': [321.3, 320.0, 322.2, 319.5, 319.15, 324.9, 309.6]})
df['Date_Time'] = pd.to_datetime(df['Date_Time'])
df = df.set_index('Date_Time')
df = pd.concat([df]*10**4)
%timeit (df.index - df.index.normalize()) == '09:15:00' # 8.67 ms
%timeit df.index.strftime('%H:%M') == '09:15' # 651 ms
%timeit df.index.time == time(9, 15) # 28.3 ms