Method: Rust::DataFrame#aggregate

Defined in:
lib/rust/core/types/dataframe.rb

#aggregate(by, **aggregators) ⇒ Object

Raises:

  • (TypeError)


379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/rust/core/types/dataframe.rb', line 379

def aggregate(by, **aggregators)
    raise TypeError, "Expected a string" unless by.is_a?(String)
    raise TypeError, "All the aggregators should be procs" unless aggregators.values.all? { |v| v.is_a?(Proc) }
    raise "Expected a block for default aggregator" unless block_given?
    
    aggregators = aggregators.map { |label, callable| [label.to_s, callable] }.to_h
    
    sorted = self.sort_by(by)
    
    current_value = nil
    partials = []
    partial = nil
    sorted.column(by).each_with_index do |value, index|
        if current_value != value
            current_value = value
            partials << partial if partial
            partial = Rust::DataFrame.new(self.column_names)
        end
        partial << sorted.fast_row(index)
    end
    partials << partial
    
    result = Rust::DataFrame.new(self.column_names)
    partials.each do |partial|
        aggregated_row = {}
        aggregated_row[by] = partial.column(by)[0]
        (self.column_names - [by]).each do |column|
            if aggregators[column]
                aggregated_row[column] = aggregators[column].call(partial.column(column))
            else
                aggregated_row[column] = yield partial.column(column)
            end
        end
        
        result << aggregated_row
    end
    
    return result
end