Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

235
Vistas
optimizar el marco de datos de la función python

Tengo este código python de la implementación de supertrend. Estoy usando el marco de datos de pandas. el código funciona bien, pero la función de supertendencia se ejecuta cada vez más lentamente a medida que aumenta la longitud del marco de datos. Me preguntaba si hay algo que pueda cambiar en el código para optimizarlo y hacerlo más rápido incluso con una gran longitud de marco de datos.

 def trueRange(df): df['prevClose'] = df['close'].shift(1) df['high-low'] = df['high'] - df['low'] df['high-pClose'] = abs(df['high'] - df['prevClose']) df['low-pClose'] = abs(df['low'] - df['prevClose']) tr = df[['high-low','high-pClose','low-pClose']].max(axis=1) return tr def averageTrueRange(df, peroid=12): df['trueRange'] = trueRange(df) the_atr = df['trueRange'].rolling(peroid).mean() return the_atr def superTrend(df, peroid=5, multipler=1.5): df['averageTrueRange'] = averageTrueRange(df, peroid=peroid) h2 = ((df['high'] + df['low']) / 2) df['Upperband'] = h2 + (multipler * df['averageTrueRange']) df['Lowerband'] = h2 - (multipler * df['averageTrueRange']) df['inUptrend'] = None for current in range(1,len(df.index)): prev = current- 1 if df['close'][current] > df['Upperband'][prev]: df['inUptrend'][current] = True elif df['close'][current] < df['Lowerband'][prev]: df['inUptrend'][current] = False else: df['inUptrend'][current] = df['inUptrend'][prev] if df['inUptrend'][current] and df['Lowerband'][current] < df['Lowerband'][prev]: df['Lowerband'][current] = df['Lowerband'][prev] if not df['inUptrend'][current] and df['Upperband'][current] > df['Upperband'][prev]: df['Upperband'][current] = df['Upperband'][prev]

versión vectorial

 def superTrend(df, peroid=5, multipler=1.5): df['averageTrueRange'] = averageTrueRange(df, peroid=peroid) h2 = ((df['high'] + df['low']) / 2) df['Upperband'] = h2 + (multipler * df['averageTrueRange']) df['Lowerband'] = h2 - (multipler * df['averageTrueRange']) df['inUptrend'] = None cond1 = df['close'].values[1:] > df['Upperband'].values[:-1] cond2 = df['close'].values[1:] < df['Lowerband'].values[:-1] df.loc[cond1, 'inUptrend'] = True df.loc[cond2, 'inUptrend'] = False df.loc[(~cond1) & (cond2), 'inUptrend'] = df['inUptrend'][:-1] df.loc[(~cond1) & (cond2) & (df['inUptrend'].values[1:] == True) & (df['Lowerband'].values[1:] < df['Lowerband'].values[:-1]), 'Lowerband'] = df['Lowerband'][:-1] df.loc[(~cond1) & (cond2) & (df['inUptrend'].values[1:] == False) & (df['Upperband'].values[1:] > df['Upperband'].values[:-1]), 'Upperband'] = df['Upperband'][:-1]

ejemplo de datos

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Aquí está la versión Numba / Numpy de su código. Tienes que convertir tu df[ 'close' ], df[ 'high' ] y df[ 'low' ] como matrices numpy para beneficio de la velocidad. No verifiqué si los valores de salida son correctos, pero entendiste la idea.

 import numpy as np from numba import jit # UNCOMMENT THIS LINE IF YOU DON'T HAVE THE OPEN PRICES # c_open = np.concatenate((np.array([np.nan]), c_close[1:])) @jit(nopython=True) def true_range(c_open, c_high, c_low): return np.maximum(np.maximum(c_high - c_low, np.abs(c_high - c_open)), np.abs(c_low - c_open)) @jit(nopython=True) def average_true_range(c_open, c_high, c_low, period=12): true_r = true_range(c_open, c_high, c_low) size = len(true_r) out = np.array([np.nan] * size) for i in range(period - 1, size): window = true_r[i - period + 1:i + 1] out[i] = np.mean(window) return out @jit(nopython=True) def super_trend(c_close, c_open, c_high, c_low, period=5, multipler=1.5): size = len(c_close) avg_true_r = average_true_range(c_open, c_high, c_low, period=period) h2 = (c_high + c_low) / 2 upper_band = h2 + (multipler * avg_true_r) lower_band = h2 - (multipler * avg_true_r) in_up_trend = np.array([np.nan] * size) for current in range(1, size): prev = current - 1 if c_close[current] > upper_band[prev]: in_up_trend[current] = True elif c_close[current] < lower_band[prev]: in_up_trend[current] = False else: in_up_trend[current] = in_up_trend[prev] if in_up_trend[current] and lower_band[current] < lower_band[prev]: lower_band[current] = lower_band[prev] if not in_up_trend[current] and upper_band[current] > upper_band[prev]: upper_band[current] = upper_band[prev] return upper_band, lower_band, in_up_trend

Editar: si no usa Heiken Ashi, no necesita cambiar los precios de cierre para obtener los últimos precios de cierre, ya que son equivalentes a los precios de apertura;)

Siéntase libre de revisar mi biblioteca de indicadores rápidos @ github

over 4 years ago · Santiago Trujillo Denunciar

0

En lugar de import pandas as pd , intente usar Modin . Modin automáticamente hace que los pandas sean mucho más rápidos. Solo import modin.pandas as pd . No necesita cambiar ningún código que no sea la importación.

Si necesita usar el método df.apply() , hay un paquete llamado Swifter . Después de pip install swifter , todo lo que necesita hacer es import swifter , y luego en lugar de hacer df.apply() , haga df.swifter.apply() . Lo conveniente es que Swifter también funciona con Modin.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda