code: def lowess(df, cols, y, f=2.0 / 3.0, iter=3):
      for col in cols:
          n = len(df[col])
          r = int(ceil(f * n))
          h = [
              np.sort(np.abs(df[col] - df[col][i]))[r] for i in range(n)
          ]
          w = np.clip(
              np.abs((df[col][:, None] - df[col][None, :]) / h),
              0.0,
              1.0,
          )
          w = (1 - w**3) ** 3
          yest = np.zeros(n)
          delta = np.ones(n)
          for iteration in range(iter):
              for i in range(n):
                  weights = delta * w[:, i]
                  b = np.array(
                      [
                          np.sum(weights * y),
                          np.sum(weights * y * df[col]),
                      ]
                  )
                  A = np.array(
                      [
                          [np.sum(weights), np.sum(weights * df[col])],
                          [
                              np.sum(weights * df[col]),
                              np.sum(weights * df[col] * df[col]),
                          ],
                      ]
                  )
                  beta = linalg.solve(A, b)
                  yest[i] = beta[0] + beta[1] * df[col][i]
  
              residuals = y - yest
              s = np.median(np.abs(residuals))
              delta = np.clip(residuals / (6.0 * s), -1, 1)
              delta = (1 - delta**2) ** 2
          df[col + "_LOWESS"] = yest
  
      return df
  
file_path: deltapy/deltapy/interact.py
imports: import numpy
  import pandas
  from statsmodels.tsa.ar_model import AR
  from timeit import default_timer
  from sklearn.tree import DecisionTreeRegressor
  from math import sin, cos, sqrt, atan2, radians, ceil
  import ta
  from gplearn.genetic import SymbolicTransformer
  from scipy import linalg
  import math
label_desc: Use image node_id 1 for calling a global function with example usage: lowess(df, cols, y, f, iter) and returns: df