J'ai des données de stock minute par minute de 2017 à 2019. Je souhaite conserver uniquement les données après 9h16 pour chaque jour, donc je souhaite convertir toutes les données entre 9h00 et 9h16 en tant que valeur de 9:16, c'est-à-dire:

La valeur de 09:16 doit être

  • open: valeur de la première donnée de 9h00 à 9h16, ici 116,00
  • high: valeur la plus élevée entre 9h00 et 9h16, ici 117,00
  • low: valeur la plus basse entre 9h00 et 9h16, ici 116,00
  • close: ce sera la valeur à 9:16, ici 113,00

                       open    high     low   close
date                                               
2017-01-02 09:08:00  116.00  116.00  116.00  116.00
2017-01-02 09:16:00  116.10  117.80  117.00  113.00
2017-01-02 09:17:00  115.50  116.20  115.50  116.20
2017-01-02 09:18:00  116.05  116.35  116.00  116.00
2017-01-02 09:19:00  116.00  116.00  115.60  115.75
...                     ...     ...     ...     ...
2029-12-29 15:56:00  259.35  259.35  259.35  259.35
2019-12-29 15:57:00  260.00  260.00  260.00  260.00
2019-12-29 15:58:00  260.00  260.00  259.35  259.35
2019-12-29 15:59:00  260.00  260.00  260.00  260.00
2019-12-29 16:36:00  259.35  259.35  259.35  259.35

Voici ce que j'ai essayé:

#Get data from/to 9:00 - 9:16 and create only one data item

convertPreTrade = df.between_time("09:00", "09:16") #09:00 - 09:16

#combine modified value to original data

df.loc[df.index.strftime("%H:%M") == "09:16" , 
    ["open","high","low","close"] ] = [convertPreTrade["open"][0],
                                        convertPreTrade["high"].max(),
                                        convertPreTrade["low"].min(),
                                        convertPreTrade['close'][-1] ] 

Mais cela ne me donnera pas de données précises

5
amitnair92 30 août 2020 à 14:17

3 réponses

Meilleure réponse

d = {'date': 'last', 'open': 'last',
     'high': 'max', 'low': 'min', 'close': 'last'}

# df.index = pd.to_datetime(df.index)
s1 = df.between_time('09:00:00', '09:16:00')
s2 = s1.reset_index().groupby(s1.index.date).agg(d).set_index('date')

df1 = pd.concat([df.drop(s1.index), s2]).sort_index()

Détails:

Utilisez DataFrame.between_time pour filtrer les lignes du dataframe df qui se situe entre le moment 09:00 et 09:16:

print(s1)
                      open   high    low  close
date                                           
2017-01-02 09:08:00  116.0  116.0  116.0  116.0
2017-01-02 09:16:00  116.1  117.8  117.0  113.0

Utilisez DataFrame.groupby pour regrouper ce dataframe filtré s1 sur date et l'agréger à l'aide du dictionnaire d:

print(s2)
                      open   high    low  close
date                                           
2017-01-02 09:16:00  116.1  117.8  116.0  113.0

Utilisez DataFrame.drop pour supprimer les lignes de la datframe d'origine df qui se situe entre l'heure 09:00-09:16, puis utilisez pd.concat pour le concaténer avec s2, enfin utiliser DataFrame.sort_index pour trier l'index:

print(df1)
                       open    high     low   close
date                                               
2017-01-02 09:16:00  116.10  117.80  116.00  113.00
2017-01-02 09:17:00  115.50  116.20  115.50  116.20
2017-01-02 09:18:00  116.05  116.35  116.00  116.00
2017-01-02 09:19:00  116.00  116.00  115.60  115.75
2019-12-29 15:57:00  260.00  260.00  260.00  260.00
2019-12-29 15:58:00  260.00  260.00  259.35  259.35
2019-12-29 15:59:00  260.00  260.00  260.00  260.00
2019-12-29 16:36:00  259.35  259.35  259.35  259.35
2029-12-29 15:56:00  259.35  259.35  259.35  259.35

5
Shubham Sharma 13 sept. 2020 à 07:20

Utilisation des données @ r-beginners et ajout de quelques lignes supplémentaires:

import pandas as pd
import numpy as np
import io

data = '''
datetime open high low close
"2017-01-02 09:08:00"  116.00  116.00  116.00  116.00
"2017-01-02 09:16:00"  116.10  117.80  117.00  113.00
"2017-01-02 09:17:00"  115.50  116.20  115.50  116.20
"2017-01-02 09:18:00"  116.05  116.35  116.00  116.00
"2017-01-02 09:19:00"  116.00  116.00  115.60  115.75
"2017-01-03 09:08:00"  259.35  259.35  259.35  259.35
"2017-01-03 09:09:00"  260.00  260.00  260.00  260.00
"2017-01-03 09:16:00"  260.00  260.00  260.00  260.00
"2017-01-03 09:17:00"  261.00  261.00  261.00  261.00
"2017-01-03 09:18:00"  262.00  262.00  262.00  262.00
"2017-12-03 09:18:00"  260.00  260.00  259.35  259.35
"2017-12-04 09:05:00"  260.00  260.00  260.00  260.00
"2017-12-04 09:22:00"  259.35  259.35  259.35  259.35
'''

df = pd.read_csv(io.StringIO(data), sep='\s+')

Le code ci-dessous démarre l'ensemble du processus. Ce n'est peut-être pas la meilleure façon de le faire, mais quelque chose de rapide et sale:

df['datetime'] = pd.to_datetime(df['datetime'])
df = df.set_index('datetime')
df['date'] = df.index.date
dates = np.unique(df.index.date)

first_rows = df.between_time('9:16', '00:00').reset_index().groupby('date').first().set_index('datetime')
first_rows['date'] = first_rows.index.date

dffs = []
for d in dates:
    df_day = df[df['date'] == d].sort_index()
    first_bar_of_the_day = first_rows[first_rows['date'] == d].copy()
    bars_until_first = df_day.loc[df_day.index <= first_bar_of_the_day.index.values[0]]
    
    if ~first_bar_of_the_day.empty:
        first_bar_of_the_day['open'] = bars_until_first['open'].values[0]
        first_bar_of_the_day['high'] = bars_until_first['high'].max()
        first_bar_of_the_day['low'] = bars_until_first['low'].min()
        first_bar_of_the_day['close'] = bars_until_first['close'].values[-1]
    
    bars_after_first = df_day.loc[df_day.index > first_bar_of_the_day.index.values[0]]
    if len(bars_after_first) > 1:
        dff = pd.concat([first_bar_of_the_day, bars_after_first])
    else:
        dff = first_bar_of_the_day.copy()
    
    print(dff)
    dffs.append(dff)
    
combined_df = pd.concat([x for x in dffs])
print(combined_df)

Les résultats imprimés sont les suivants: dff pour différentes dates

                       open    high    low   close        date
datetime                                                      
2017-01-02 09:16:00  116.00  117.80  116.0  113.00  2017-01-02
2017-01-02 09:17:00  115.50  116.20  115.5  116.20  2017-01-02
2017-01-02 09:18:00  116.05  116.35  116.0  116.00  2017-01-02
2017-01-02 09:19:00  116.00  116.00  115.6  115.75  2017-01-02
                       open   high     low  close        date
datetime                                                     
2017-01-03 09:16:00  259.35  260.0  259.35  260.0  2017-01-03
2017-01-03 09:17:00  261.00  261.0  261.00  261.0  2017-01-03
2017-01-03 09:18:00  262.00  262.0  262.00  262.0  2017-01-03
                      open   high     low   close        date
datetime                                                     
2017-12-03 09:18:00  260.0  260.0  259.35  259.35  2017-12-03
                      open   high     low   close        date
datetime                                                     
2017-12-04 09:22:00  260.0  260.0  259.35  259.35  2017-12-04

Le combined_df

                       open    high     low   close        date
datetime                                                       
2017-01-02 09:16:00  116.00  117.80  116.00  113.00  2017-01-02
2017-01-02 09:17:00  115.50  116.20  115.50  116.20  2017-01-02
2017-01-02 09:18:00  116.05  116.35  116.00  116.00  2017-01-02
2017-01-02 09:19:00  116.00  116.00  115.60  115.75  2017-01-02
2017-01-03 09:16:00  259.35  260.00  259.35  260.00  2017-01-03
2017-01-03 09:17:00  261.00  261.00  261.00  261.00  2017-01-03
2017-01-03 09:18:00  262.00  262.00  262.00  262.00  2017-01-03
2017-12-03 09:18:00  260.00  260.00  259.35  259.35  2017-12-03
2017-12-04 09:22:00  260.00  260.00  259.35  259.35  2017-12-04

Note latérale: je ne suis pas trop sûr si votre façon de purger les données est la meilleure, peut-être pourriez-vous regarder si vous devez ignorer complètement l'heure avant 9h16 tous les jours, ou même faire une analyse pour vérifier la volatilité pour les 15 premiers. minutes pour décider.

1
lrh09 1 sept. 2020 à 15:50

Extrait de 9h00 à 9h16. Les bases de données sont regroupées par année, mois et jour et calculées par rapport aux valeurs OHLC. La logique utilise votre code. Enfin, vous ajoutez une colonne de date à 9h16. Comme nous n'avons pas toutes les données, nous avons peut-être omis certaines considérations, mais la forme de base reste la même.

import pandas as pd
import numpy as np
import io

data = '''
date open high low close
"2017-01-02 09:08:00"  116.00  116.00  116.00  116.00
"2017-01-02 09:16:00"  116.10  117.80  117.00  113.00
"2017-01-02 09:17:00"  115.50  116.20  115.50  116.20
"2017-01-02 09:18:00"  116.05  116.35  116.00  116.00
"2017-01-02 09:19:00"  116.00  116.00  115.60  115.75
"2017-01-03 09:08:00"  259.35  259.35  259.35  259.35
"2017-01-03 09:09:00"  260.00  260.00  260.00  260.00
"2017-12-03 09:18:00"  260.00  260.00  259.35  259.35
"2017-12-04 09:05:00"  260.00  260.00  260.00  260.00
"2017-12-04 09:22:00"  259.35  259.35  259.35  259.35
'''

df = pd.read_csv(io.StringIO(data), sep='\s+')

df.reset_index(drop=True, inplace=True)
df['date'] = pd.to_datetime(df['date'])
# 9:00-9:16
df_start = df[((df['date'].dt.hour == 9) & (df['date'].dt.minute >= 0)) & ((df['date'].dt.hour == 9) & (df['date'].dt.minute <=16))]
# calculate
df_new = (df_start.groupby([df['date'].dt.year, df['date'].dt.month, df['date'].dt.day])
            .agg(open_first=('open', lambda x: x.iloc[0,]),
                 high_max=('high','max'),
                 low_min=('low', 'min'),
                 close_shift=('close', lambda x: x.iloc[-1,])))
df_new.index.names = ['year', 'month', 'day']
df_new.reset_index(inplace=True)
df_new['date'] = df_new['year'].astype(str)+'-'+df_new['month'].astype(str)+'-'+df_new['day'].astype(str)+' 09:16:00'

year    month   day open_first  high_max    low_min close_shift date
0   2017    1   2   116.00  117.8   116.00  113.0   2017-1-2 09:16:00
1   2017    1   3   259.35  260.0   259.35  260.0   2017-1-3 09:16:00
2   2017    12  4   260.00  260.0   260.00  260.0   2017-12-4 09:16:00
2
r-beginners 30 août 2020 à 14:31