def reduce(init=nil)
        result_hash = groups_by_idx.each_with_object({}) do |(group, indices), h|
          group_indices = indices.map { |v| @context.index.to_a[v] }

          grouped_result = init
          group_indices.each do |idx|
            grouped_result = yield(grouped_result, @context.row[idx])
          end

          h[group] = grouped_result
        end

        index = get_grouped_index(result_hash.keys)

        Daru::Vector.new(result_hash.values, index: index)
      end
Iteratively applies a function to the values in a group and accumulates the result.
@param init (nil) The initial value of the accumulator.
@yieldparam block [Proc] A proc or lambda that accepts two arguments.  The first argument
is the accumulated result.  The second argument is a DataFrame row.
@example Usage of reduce
df = Daru::DataFrame.new({
a: ['a','b'] * 3,
b: [1,2,3] * 2,
c: 'A'..'F'
})
df.group_by([:a]).reduce('') { |result, row| result += row[:c]; result }
# =>
# #<Daru::Vector:70343147159900 @name = nil @size = 2 >
#     nil
#   a ACE
#   b BDF