code: def pls(df):
      
  
      if not sklearn:
          assert('This library depends on scikit-learn (sklearn) to perform PLS-based imputation')
  
      df = df.copy()
      df[np.isinf(df)] = np.nan
  
      dfo = df.dropna(how='any', axis=0)
      dfo = dfo.astype(np.float64)
      
      dfi = df.copy()
      imputed = df.isnull() #Keep track of what's real
  
      # List of proteins with missing values in their rows
      missing_values = df[ np.sum(np.isnan(df), axis=1) > 0 ].index
      ix_mask = np.arange(0, df.shape[1])
      total_n = len(missing_values)
  
      #dfi = df.fillna(0)
  
      plsr = PLSRegression(n_components=2)
  
      for n, p in enumerate(missing_values.values):
          # Generate model for this protein from missing data
          target = df.loc[p].values.copy().T
  
          ixes = ix_mask[ np.isnan(target) ]
  
          # Fill missing values with row median for calculation
          target[np.isnan(target)] = np.nanmedian(target)
          plsr.fit(dfo.values.T, target)
  
          # For each missing value, calculate imputed value from the column data input
          for ix in ixes:
              imputv = plsr.predict(dfo.iloc[:, ix])[0]
              dfi.ix[p, ix] = imputv
  
          print("%d%%" % ((n/total_n)*100), end="\r")
  
  
      return dfi, imputed
docs: A simple implementation of a least-squares approach to imputation using partial least squares
      regression (PLS).
  
      :param df:
      :return: