Frequency counter with most-common, merge, and percentage operations
gem install philiprehberger-counterFrequency counter with most-common, merge, and percentage operations
Add to your Gemfile:
gem "philiprehberger-counter"
Or install directly:
gem install philiprehberger-counter
require "philiprehberger/counter"
counter = Philiprehberger::Counter.new(%w[a b a c a b])
counter['a'] # => 3
counter.most_common(2) # => [["a", 3], ["b", 2]]
counter.total # => 6
counter.percentage('a') # => 50.0
counter = Philiprehberger::Counter.new
counter.increment('x')
counter.increment('x', 5)
counter['x'] # => 6
a = Philiprehberger::Counter.new(%w[x x y])
b = Philiprehberger::Counter.new(%w[x z])
merged = a.merge(b)
merged['x'] # => 3
counter = Philiprehberger::Counter.new(%w[a b a])
counter.map { |key, count| "#{key}: #{count}" }
# => ["a: 2", "b: 1"]
counter = Philiprehberger::Counter.new(%w[a a a b])
counter.decrement('a') # => 2
counter.decrement('a', 2) # => 0
counter.reset('b') # removes 'b'
counter.reset # clears all
counter = Philiprehberger::Counter.new
counter.update(%w[x y x z]) # count from enumerable
counter.update({ 'x' => 10 }) # add from hash
counter['x'] # => 12
counter = Philiprehberger::Counter.new(%w[a a b c])
counter.delete('a') # => 2 (removes key entirely)
counter.delete('z') # => nil (key not present)
counter = Philiprehberger::Counter.new(%w[a b a c a b])
counter.max_count # => ["a", 3]
counter.min_count # => ["c", 1]
counter.mode # => "a"
counter = Philiprehberger::Counter.new(%w[a b a])
json = counter.to_json # => '{"a":2,"b":1}'
restored = Philiprehberger::Counter.from_json(json)
restored['a'] # => 2
counter = Philiprehberger::Counter.new(%w[a a a b])
counter.sample # => "a" (weighted by count)
counter.sample(3) # => ["a", "a", "b"] (array of weighted samples)
counter = Philiprehberger::Counter.new(%w[a b a])
counter.keys # => ["a", "b"]
counter.values # => [2, 1]
counter = Philiprehberger::Counter.new(%w[a a a b b c])
frequent = counter.filter_by_count(min: 2)
frequent.to_h # => {"a" => 3, "b" => 2}
counter = Philiprehberger::Counter.new(%w[a b c d])
counter.entropy # => 2.0 (uniform 4-key distribution, bits)
skewed = Philiprehberger::Counter.new(%w[a a a a b])
skewed.entropy # => ~0.7219 (less than uniform upper bound)
before = Philiprehberger::Counter.new(%w[errors errors warnings])
after = Philiprehberger::Counter.new(%w[errors errors errors warnings infos])
after.diff(before)
# => { "errors" => 1, "infos" => 1 }
Returns a Hash of { key => signed_delta } for every key whose count
changed; equal counts are pruned. Useful for change detection between
snapshots.
Ratio of unique keys to total observations — a simple diversity metric.
1.0 means every observation was unique; small values mean a few keys
dominate.
Philiprehberger::Counter.new(%w[a b c d]).unique_ratio # => 1.0
Philiprehberger::Counter.new(%w[a a a a]).unique_ratio # => 0.25
Philiprehberger::Counter.new(%w[a a b b b c]).unique_ratio # => 0.5
| Method | Description |
|---|---|
Counter.new(enumerable) | Create a counter from an enumerable |
#[key] | Get count for a key |
#increment(key, n) | Increment count for a key |
#most_common(n) | Return n most common elements |
#least_common(n) | Return n least common elements |
#total | Sum of all counts |
#merge(other) | Merge two counters |
#subtract(other) | Subtract another counter |
#diff(other) | Hash of {key => signed_delta} for keys whose counts differ |
#percentage(key) | Percentage of key relative to total |
#decrement(key, n) | Decrement count for a key, floored at zero |
#reset(key) | Reset a specific key or clear all counts |
#update(data) | Batch update from a Hash or Enumerable |
#delete(key) | Remove a key entirely, returns count or nil |
#max_count | Key-count pair with highest count |
#min_count | Key-count pair with lowest count |
#mode | Most-common key (just the key, not the pair) |
#to_json | Serialize counter to JSON string |
.from_json(str) | Deserialize counter from JSON string |
#sample(n) | Weighted random sample based on counts |
#keys | Return all tracked keys |
#values | Return all count values |
#filter_by_count(min:, max:) | Filter entries by count range |
#entropy | Shannon entropy of the count distribution in bits |
#unique_ratio | Ratio of unique keys to total observations (size / total); 0.0 for empty counters |
#to_h | Convert to a plain hash |
#size | Number of unique keys |
bundle install
bundle exec rspec
bundle exec rubocop
If you find this project useful: