def cast_aggregation_options(options)
      vects, non_vects = options.keys.partition { |k| @vectors.include?(k) }

      over_vectors = true

      if non_vects.any?
        options = options.clone

        vects.each do |name|
          proc_on_vect = options[name].to_proc
          options[name] = ->(sub_df) { proc_on_vect.call(sub_df[name]) }
        end

        over_vectors = false
      end

      [over_vectors, options]
    end
def cast_aggregation_options(options)
      vects, non_vects = options.keys.partition { |k| @vectors.include?(k) }

      over_vectors = true

      if non_vects.any?
        options = options.clone

        vects.each do |name|
          proc_on_vect = options[name].to_proc
          options[name] = ->(sub_df) { proc_on_vect.call(sub_df[name]) }
        end

        over_vectors = false
      end

      [over_vectors, options]
    end
convert operations over sub-vectors to operations over sub-dfs when it improves perf
 note: we don't always "cast" because aggregation over a single vector / a few vector is faster
   than aggregation over (sub-)dfs