code: def dapply(self, fn, pairwise=False, symmetric=True, diagonal=False, block=None, **kwargs):
      search_keys = [k for k, v in kwargs.items() if isinstance(v, list) and len(v) > 1]
      functions = util.make_list(fn)
      search = list(product(functions, util.dict_product(kwargs)))
      results = []
      for fn, kw in search:
          if not pairwise:
              r = self.index.to_series().apply(lambda step: fn(step, **kw))
          else:
              r = apply_pairwise(self, fn,
                                 symmetric=symmetric, diagonal=diagonal, block=block,
                                 **kw)
          name = [] if len(functions) == 1 else [fn.__name__]
          name += util.dict_subset(kw, search_keys).values()
          if isinstance(r, pd.DataFrame):
              columns = pd.MultiIndex.from_tuples(
                      [tuple(name + util.make_list(c)) for c in r.columns])
              r.columns = columns
          else:
              r.name = tuple(name)
          results.append(r)
      if len(results) > 1:
          result = pd.concat(results, axis=1)
          column_names = [] if len(functions) == 1 else [None]
          column_names += search_keys
          column_names += [None]*(len(result.columns.names)-len(column_names))
          result.columns.names = column_names
          return StepFrame(result)
      else:
          result = results[0]
          if isinstance(result, pd.DataFrame):
              return StepFrame(result)
          else:
              result.name = functions[0].__name__
              return StepSeries(result)