web-dev-qa-db-fra.com

Pandas Agrégation OHLC sur les données OHLC

Je comprends que le rééchantillonnage OHLC des données de séries chronologiques dans Pandas, en utilisant une colonne de données, fonctionnera parfaitement, par exemple sur le cadre de données suivant:

>>df
ctime       openbid
1443654000  1.11700
1443654060  1.11700
...

df['ctime']  = pd.to_datetime(df['ctime'], unit='s')
df           = df.set_index('ctime')
df.resample('1H',  how='ohlc', axis=0, fill_method='bfill')


>>>
                     open     high     low       close
ctime                                                   
2015-09-30 23:00:00  1.11700  1.11700  1.11687   1.11697
2015-09-30 24:00:00  1.11700  1.11712  1.11697   1.11697
...

Mais que dois-je faire si les données sont déjà au format OHLC? D'après ce que je peux rassembler, la méthode OHLC de l'API calcule une tranche OHLC pour chaque colonne, donc si mes données sont au format:

             ctime  openbid  highbid   lowbid  closebid
0       1443654000  1.11700  1.11700  1.11687   1.11697
1       1443654060  1.11700  1.11712  1.11697   1.11697
2       1443654120  1.11701  1.11708  1.11699   1.11708

Lorsque j'essaie de rééchantillonner, j'obtiens un OHLC pour chacune des colonnes, comme ceci:

                     openbid                             highbid           \
                        open     high      low    close     open     high   
ctime                                                                       
2015-09-30 23:00:00  1.11700  1.11700  1.11700  1.11700  1.11700  1.11712   
2015-09-30 23:01:00  1.11701  1.11701  1.11701  1.11701  1.11708  1.11708 
...
                                        lowbid                             \
                         low    close     open     high      low    close   
ctime                                                                       
2015-09-30 23:00:00  1.11700  1.11712  1.11687  1.11697  1.11687  1.11697   
2015-09-30 23:01:00  1.11708  1.11708  1.11699  1.11699  1.11699  1.11699  
...

                    closebid                             
                        open     high      low    close  
ctime                                                    
2015-09-30 23:00:00  1.11697  1.11697  1.11697  1.11697  
2015-09-30 23:01:00  1.11708  1.11708  1.11708  1.11708  

Existe-t-il une solution rapide (ish) à cela que quelqu'un est prêt à partager s'il vous plaît, sans que je doive me mettre à genoux dans le manuel pandas?

Merci.

ps, il y a cette réponse - Conversion des données de stock OHLC dans un délai différent avec python et pandas - mais c'était il y a 4 ans, donc j'espère qu'il y a eu certains progrès.

25
user3439187

Ceci est similaire à la réponse que vous avez liée, mais elle est un peu plus propre et plus rapide, car elle utilise les agrégations optimisées, plutôt que les lambdas.

Notez que la syntaxe resample(...).agg(...) requiert pandas version 0.18.0.

In [101]: df.resample('1H').agg({'openbid': 'first', 
                                 'highbid': 'max', 
                                 'lowbid': 'min', 
                                 'closebid': 'last'})
Out[101]: 
                      lowbid  highbid  closebid  openbid
ctime                                                   
2015-09-30 23:00:00  1.11687  1.11712   1.11708    1.117
36
chrisb

Vous devez utiliser un OrderedDict pour conserver l'ordre des lignes dans les nouvelles versions de pandas, comme ceci:

import pandas as pd
from collections import OrderedDict

df['ctime'] = pd.to_datetime(df['ctime'], unit='s')
df = btceur.set_index('ctime')
df = df.resample('5Min').agg(
    OrderedDict([
        ('open', 'first'),
        ('high', 'max'),
        ('low', 'min'),
        ('close', 'last'),
        ('volume', 'sum'),
    ])
)
3
Benjamin Crouzier

Étant donné une trame de données avec des colonnes de prix et de montant

def agg_ohlcv(x):
    arr = x['price'].values
    names = {
        'low': min(arr) if len(arr) > 0 else np.nan,
        'high': max(arr) if len(arr) > 0 else np.nan,
        'open': arr[0] if len(arr) > 0 else np.nan,
        'close': arr[-1] if len(arr) > 0 else np.nan,
        'volume': sum(x['amount'].values) if len(x['amount'].values) > 0 else 0,
    }
    return pd.Series(names)

df = df.resample('1min').apply(agg_ohlcv)
df = df.ffill()
0
Ben