You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySpark实现Aroon指标:按组计算最值与当前行的间隔行数

Solution for Implementing Aroon Up, Aroon Dn, and Aroon Oscillator

Got it, let's build out the missing pieces to calculate those period gaps and finish the Aroon indicators. Here's how to extend your existing PySpark code step by step:

First, we need to track row positions within each group so we can calculate the distance between the current row and the row where the max/min occurred. Then we'll compute the period gaps, and finally derive the Aroon metrics.

Step 1: Import Required Functions

Make sure you have these imports at the top of your script:

from pyspark.sql.functions import row_number, first, when, max, min
from pyspark.sql.window import Window

Step 2: Add Grouped Row Numbers

We'll assign a sequential row number to each entry within its Name group, ordered by Date—this helps us measure the row interval:

def myFunction(myData):
    df = myData
    col = 'Date'
    groupCols = ['Name']
    
    # Add row number within each group (ordered by Date)
    row_window = Window.partitionBy(groupCols).orderBy(df[col].asc())
    df = df.withColumn("row_num", row_number().over(row_window))
    
    # Your existing window and max/min calculations
    window=Window.partitionBy(groupCols).orderBy(df[col].asc()).rowsBetween(-11, 0)
    max_value = max(df['value']).over(window)
    min_value = min(df['value']).over(window)
    df = df.withColumn('max', max_value)
    df = df.withColumn('min', min_value)

Step 3: Calculate Periods Since Max/Min

Next, we'll find the row number of the most recent max/min in the sliding window, then compute the interval between that row and the current row:

# Get row number of the most recent max value in the window
    max_row_window = window.orderBy(when(df["value"] == df["max"], 0).otherwise(1), df["row_num"].desc())
    max_row_num = first(df["row_num"], ignorenulls=True).over(max_row_window)
    df = df.withColumn("periods_since_max", df["row_num"] - max_row_num)
    
    # Get row number of the most recent min value in the window
    min_row_window = window.orderBy(when(df["value"] == df["min"], 0).otherwise(1), df["row_num"].desc())
    min_row_num = first(df["row_num"], ignorenulls=True).over(min_row_window)
    df = df.withColumn("periods_since_min", df["row_num"] - min_row_num)

Note: The orderBy clause ensures we prioritize rows where the value matches the window's max/min, and if there are duplicates, we pick the most recent one (highest row number).

Step 4: Compute Aroon Indicators

Now we can calculate the final Aroon metrics using the period gaps:

# Calculate Aroon Up, Aroon Dn, and Aroon Oscillator
    df = df.withColumn("aroon_up", ((12 - df["periods_since_max"]) / 12) * 100)
    df = df.withColumn("aroon_dn", ((12 - df["periods_since_min"]) / 12) * 100)
    df = df.withColumn("aroon_oscillator", df["aroon_up"] - df["aroon_dn"])
    
    return df

Full Combined Code

Putting it all together, the complete function looks like this:

from pyspark.sql.functions import row_number, first, when, max, min
from pyspark.sql.window import Window

def myFunction(myData):
    df = myData
    col = 'Date'
    groupCols = ['Name']
    
    # Add row number within each group (ordered by Date)
    row_window = Window.partitionBy(groupCols).orderBy(df[col].asc())
    df = df.withColumn("row_num", row_number().over(row_window))
    
    # Sliding window for max/min calculations (12-period window: current + previous 11 rows)
    window=Window.partitionBy(groupCols).orderBy(df[col].asc()).rowsBetween(-11, 0)
    max_value = max(df['value']).over(window)
    min_value = min(df['value']).over(window)
    df = df.withColumn('max', max_value)
    df = df.withColumn('min', min_value)
    
    # Get row number of most recent max in window
    max_row_window = window.orderBy(when(df["value"] == df["max"], 0).otherwise(1), df["row_num"].desc())
    max_row_num = first(df["row_num"], ignorenulls=True).over(max_row_window)
    df = df.withColumn("periods_since_max", df["row_num"] - max_row_num)
    
    # Get row number of most recent min in window
    min_row_window = window.orderBy(when(df["value"] == df["min"], 0).otherwise(1), df["row_num"].desc())
    min_row_num = first(df["row_num"], ignorenulls=True).over(min_row_window)
    df = df.withColumn("periods_since_min", df["row_num"] - min_row_num)
    
    # Calculate Aroon indicators
    df = df.withColumn("aroon_up", ((12 - df["periods_since_max"]) / 12) * 100)
    df = df.withColumn("aroon_dn", ((12 - df["periods_since_min"]) / 12) * 100)
    df = df.withColumn("aroon_oscillator", df["aroon_up"] - df["aroon_dn"])
    
    return df

How It Works

  • Row Numbers: We use row_number() to assign a unique sequence to each row in its group, ordered by date—this lets us measure how many rows have passed since the max/min.
  • Finding Recent Max/Min: The custom window ordering ensures we grab the most recent occurrence of the window's max/min value (critical if there are duplicate peaks/troughs).
  • Aroon Calculations: The formulas follow the standard Aroon definitions:
    • Aroon Up measures how long ago the highest high occurred in the window (100 means it's the current row).
    • Aroon Dn does the same for the lowest low.
    • Aroon Oscillator is the difference between the two, showing trend strength and direction.

内容的提问来源于stack exchange,提问作者user9722371

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:45:36