histogram 0.2.2.0 → 0.2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/histogram.rb +50 -31
- data/lib/histogram/version.rb +1 -1
- data/spec/histogram_spec.rb +6 -1
- data/spec/spec_helper.rb +1 -17
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87b16b66fb1ed20c22d818250d368d39fc3445fc
|
4
|
+
data.tar.gz: f6bf7bd712834fc3028a6e8c2ade8a20274ce004
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d19f5747ea74d6a9b70d9b9c22a0d0321f2be8b82679fbd1cbd4226bc9fae828775ded31c7c033bd3153c3528d5b238c1a8ff37bd6e77dcf2759137700fb690a
|
7
|
+
data.tar.gz: 6dadf8f32857060dc8b70bf30493f21b9a63e8caaf99f612a4db42877bc6a00350775cd24d6e9c38b24042cb7b1c6c9bc6be6aeac43d3f040dabd0e13e751d5a
|
data/README.md
CHANGED
@@ -65,7 +65,7 @@ Big thanks to those who have made contributions!
|
|
65
65
|
|
66
66
|
* deal with zero std ([Greg Dean](https://github.com/gsdean))
|
67
67
|
* support for 1.8.7 and jruby ([Kiera Radman](https://github.com/kierarad))
|
68
|
-
* reorder nan checks
|
68
|
+
* reorder nan checks to fix zero stdev arrays ([arjun810](https://github.com/arjun810))
|
69
69
|
|
70
70
|
## See Also
|
71
71
|
|
data/lib/histogram.rb
CHANGED
@@ -40,21 +40,27 @@ module Histogram
|
|
40
40
|
end
|
41
41
|
std_dev = _sum_sq - ((_sum * _sum)/_len)
|
42
42
|
std_dev /= ( _len > 1 ? _len-1 : 1 )
|
43
|
-
|
43
|
+
sqrt_of_std_dev =
|
44
|
+
begin
|
45
|
+
Math.sqrt(std_dev)
|
46
|
+
rescue Math::DomainError
|
47
|
+
0.0
|
48
|
+
end
|
49
|
+
[_sum.to_f/_len, sqrt_of_std_dev]
|
44
50
|
end
|
45
51
|
|
46
|
-
# opts:
|
52
|
+
# opts:
|
47
53
|
#
|
48
54
|
# defaults:
|
49
55
|
# :method => :moore_mccabe, :tukey
|
50
56
|
# :sorted => false
|
51
|
-
#
|
57
|
+
#
|
52
58
|
def iqrange(obj, opts={})
|
53
59
|
opt = {:method => DEFAULT_QUARTILE_METHOD, :sorted => false}.merge( opts )
|
54
60
|
srted = opt[:sorted] ? obj : obj.sort
|
55
61
|
sz = srted.size
|
56
62
|
return 0 if sz == 1
|
57
|
-
answer =
|
63
|
+
answer =
|
58
64
|
case opt[:method]
|
59
65
|
when :tukey
|
60
66
|
hi_idx = sz / 2
|
@@ -90,25 +96,30 @@ module Histogram
|
|
90
96
|
if methd == :middle
|
91
97
|
[:scott, :sturges, :fd].map {|v| number_of_bins(v) }.sort[1]
|
92
98
|
else
|
93
|
-
nbins =
|
99
|
+
nbins =
|
94
100
|
case methd
|
95
101
|
when :scott
|
96
102
|
range = (self.max - self.min).to_f
|
97
|
-
(mean, stddev) = Histogram.sample_stats(self)
|
98
|
-
|
103
|
+
(mean, stddev) = Histogram.sample_stats(self)
|
104
|
+
if stddev == 0.0
|
105
|
+
1
|
106
|
+
else
|
107
|
+
range / ( 3.5*stddev*(self.size**(-1.0/3)) )
|
108
|
+
end
|
99
109
|
when :sturges
|
100
110
|
1 + Math::log2(self.size)
|
101
111
|
when :fd
|
102
112
|
2 * Histogram.iqrange(self, :method => quartile_method) * (self.size**(-1.0/3))
|
103
113
|
end
|
104
|
-
nbins
|
105
|
-
|
114
|
+
if nbins > self.size || nbins.to_f.nan? || nbins <= 0
|
115
|
+
nbins = 1
|
116
|
+
end
|
106
117
|
nbins.ceil.to_i
|
107
118
|
end
|
108
119
|
end
|
109
120
|
|
110
121
|
# Returns [bins, freqs]
|
111
|
-
#
|
122
|
+
#
|
112
123
|
# histogram(bins, opts)
|
113
124
|
# histogram(opts)
|
114
125
|
#
|
@@ -127,23 +138,23 @@ module Histogram
|
|
127
138
|
# :bin_width => <float> width of a bin (overrides :bins)
|
128
139
|
# :min => <float> # explicitly set the min
|
129
140
|
# :max => <float> # explicitly set the max val
|
130
|
-
#
|
141
|
+
#
|
131
142
|
# :other_sets => an array of other sets to histogram
|
132
143
|
#
|
133
|
-
# Examples
|
144
|
+
# Examples
|
134
145
|
#
|
135
146
|
# require 'histogram/array'
|
136
147
|
# ar = [-2,1,2,3,3,3,4,5,6,6]
|
137
148
|
# # these return: [bins, freqencies]
|
138
149
|
# ar.histogram(20) # use 20 bins
|
139
150
|
# ar.histogram([-3,-1,4,5,6], :bin_boundary => :avg) # custom bins
|
140
|
-
#
|
151
|
+
#
|
141
152
|
# # returns [bins, freq1, freq2 ...]
|
142
153
|
# (bins, *freqs) = ar.histogram(30, :bin_boundary => :avg, :other_sets => [3,3,4,4,5], [-1,0,0,3,3,6])
|
143
154
|
# (ar_freqs, other1, other2) = freqs
|
144
155
|
#
|
145
156
|
# # histogramming with weights
|
146
|
-
# w_weights.histogram(20, :weights => [3,3,8,8,9,9,3,3,3,3])
|
157
|
+
# w_weights.histogram(20, :weights => [3,3,8,8,9,9,3,3,3,3])
|
147
158
|
#
|
148
159
|
# # with NArray
|
149
160
|
# require 'histogram/narray'
|
@@ -165,7 +176,7 @@ module Histogram
|
|
165
176
|
# to share the exact same bins. In this case returns [bins, freqs(caller),
|
166
177
|
# freqs1, freqs2 ...]
|
167
178
|
# * Can also deal with weights. :weights should provide parallel arrays to
|
168
|
-
# the caller and any :other_sets provided.
|
179
|
+
# the caller and any :other_sets provided.
|
169
180
|
def histogram(*args)
|
170
181
|
make_freqs_proc = lambda do |obj, len|
|
171
182
|
if obj.is_a?(Array)
|
@@ -202,13 +213,13 @@ module Histogram
|
|
202
213
|
other_sets = opts[:other_sets]
|
203
214
|
|
204
215
|
bins_array_like = bins.kind_of?(Array) || bins.kind_of?(NArray) || opts[:bin_width]
|
205
|
-
all = [self] + other_sets
|
216
|
+
all = [self] + other_sets
|
206
217
|
|
207
218
|
if bins.is_a?(Symbol)
|
208
219
|
bins = number_of_bins(bins)
|
209
220
|
end
|
210
221
|
|
211
|
-
weights =
|
222
|
+
weights =
|
212
223
|
if opts[:weights]
|
213
224
|
have_frac_freqs = true
|
214
225
|
opts[:weights][0].is_a?(Numeric) ? [ opts[:weights] ] : opts[:weights]
|
@@ -217,8 +228,8 @@ module Histogram
|
|
217
228
|
end
|
218
229
|
|
219
230
|
# we need to know the limits of the bins if we need to define our own bins
|
220
|
-
if opts[:bin_width] || !bins_array_like
|
221
|
-
calc_min, calc_max =
|
231
|
+
if opts[:bin_width] || !bins_array_like
|
232
|
+
calc_min, calc_max =
|
222
233
|
unless opts[:min] && opts[:max]
|
223
234
|
(mins, maxs) = all.map {|ar| Histogram.minmax(ar) }.transpose
|
224
235
|
[mins.min, maxs.max]
|
@@ -238,9 +249,9 @@ module Histogram
|
|
238
249
|
########################################################
|
239
250
|
# ARRAY BINS:
|
240
251
|
########################################################
|
241
|
-
_bins =
|
252
|
+
_bins =
|
242
253
|
if bins.is_a?(Array)
|
243
|
-
bins.map {|v| v.to_f }
|
254
|
+
bins.map {|v| v.to_f }
|
244
255
|
elsif bins.is_a?(NArray)
|
245
256
|
bins.to_f
|
246
257
|
end
|
@@ -250,11 +261,11 @@ module Histogram
|
|
250
261
|
|
251
262
|
_freqs = make_freqs_proc.call(xvals, bins.size)
|
252
263
|
|
253
|
-
break_points = []
|
264
|
+
break_points = []
|
254
265
|
(0...(bins.size)).each do |i|
|
255
266
|
bin = bins[i]
|
256
267
|
break if i == (bins.size - 1)
|
257
|
-
break_points << avg_ints(bin,bins[i+1])
|
268
|
+
break_points << avg_ints(bin,bins[i+1])
|
258
269
|
end
|
259
270
|
(0...(xvals.size)).each do |i|
|
260
271
|
val = xvals[i]
|
@@ -262,9 +273,9 @@ module Histogram
|
|
262
273
|
if val < break_points.first
|
263
274
|
_freqs[0] += height
|
264
275
|
elsif val >= break_points.last
|
265
|
-
_freqs[-1] += height
|
276
|
+
_freqs[-1] += height
|
266
277
|
else
|
267
|
-
(0...(break_points.size-1)).each do |i|
|
278
|
+
(0...(break_points.size-1)).each do |i|
|
268
279
|
if val >= break_points[i] && val < break_points[i+1]
|
269
280
|
_freqs[i+1] += height
|
270
281
|
break
|
@@ -272,7 +283,7 @@ module Histogram
|
|
272
283
|
end
|
273
284
|
end
|
274
285
|
end
|
275
|
-
_freqs
|
286
|
+
_freqs
|
276
287
|
end
|
277
288
|
when :min
|
278
289
|
freqs_ar = all.zip(weights).map do |xvals, yvals|
|
@@ -305,7 +316,7 @@ module Histogram
|
|
305
316
|
dmin = _min.to_f
|
306
317
|
conv = _max == _min ? 0 : bins.to_f/(_max - _min)
|
307
318
|
|
308
|
-
_bins =
|
319
|
+
_bins =
|
309
320
|
if self.is_a?(Array)
|
310
321
|
Array.new(bins)
|
311
322
|
elsif self.is_a?(NArray)
|
@@ -335,12 +346,20 @@ module Histogram
|
|
335
346
|
iconv = 1.0/conv
|
336
347
|
case bin_boundary
|
337
348
|
when :avg
|
338
|
-
|
339
|
-
_bins[
|
349
|
+
if bins == 1
|
350
|
+
_bins[0] = self.to_a.inject(0.0) {|sum, val| sum + val } / self.size
|
351
|
+
else
|
352
|
+
(0...bins).each do |i|
|
353
|
+
_bins[i] = ((i+0.5) * iconv) + dmin
|
354
|
+
end
|
340
355
|
end
|
341
356
|
when :min
|
342
|
-
|
343
|
-
_bins[
|
357
|
+
if bins == 1
|
358
|
+
_bins[0] = self.min
|
359
|
+
else
|
360
|
+
(0...bins).each do |i|
|
361
|
+
_bins[i] = (i * iconv) + dmin
|
362
|
+
end
|
344
363
|
end
|
345
364
|
end
|
346
365
|
end
|
data/lib/histogram/version.rb
CHANGED
data/spec/histogram_spec.rb
CHANGED
@@ -106,6 +106,10 @@ shared_examples 'something that can histogram' do
|
|
106
106
|
bins, freq = obj7.histogram(:middle)
|
107
107
|
end
|
108
108
|
|
109
|
+
it 'can handle all the same value' do
|
110
|
+
bins, freq = obj8.histogram
|
111
|
+
end
|
112
|
+
|
109
113
|
end
|
110
114
|
|
111
115
|
describe Histogram do
|
@@ -117,7 +121,8 @@ describe Histogram do
|
|
117
121
|
:obj4 => [2, 2, 2, 2, 2, 4],
|
118
122
|
:obj5 => [1,2,3,3,3,4,5,6,7,8],
|
119
123
|
:obj6 => [0,0,0,0,0],
|
120
|
-
:obj7 => [0]
|
124
|
+
:obj7 => [0],
|
125
|
+
:obj8 => [1e-1, 1e-1, 1e-1, 1e-1],
|
121
126
|
}
|
122
127
|
data = tmp.each {|k,v| [k, v.map(&:to_f).extend(Histogram)] }
|
123
128
|
|
data/spec/spec_helper.rb
CHANGED
@@ -3,24 +3,8 @@ SimpleCov.start
|
|
3
3
|
|
4
4
|
require 'rspec'
|
5
5
|
|
6
|
-
require 'rspec/core/formatters/progress_formatter'
|
7
|
-
# doesn't say so much about pending guys
|
8
|
-
class QuietPendingFormatter < RSpec::Core::Formatters::ProgressFormatter
|
9
|
-
def example_pending(example)
|
10
|
-
output.print pending_color('*')
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
require 'rspec/core/formatters/documentation_formatter'
|
15
|
-
class QuietPendingDocFormatter < RSpec::Core::Formatters::DocumentationFormatter
|
16
|
-
def example_pending(example)
|
17
|
-
output.puts pending_color( "<pending>: #{example.execution_result[:pending_message]}" )
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
6
|
RSpec.configure do |config|
|
22
|
-
config.
|
23
|
-
config.formatter = QuietPendingDocFormatter
|
7
|
+
config.expect_with(:rspec) { |c| c.syntax = :should }
|
24
8
|
config.color = true
|
25
9
|
end
|
26
10
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: histogram
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John T. Prince
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-09-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
version: '0'
|
137
137
|
requirements: []
|
138
138
|
rubyforge_project:
|
139
|
-
rubygems_version: 2.
|
139
|
+
rubygems_version: 2.4.5
|
140
140
|
signing_key:
|
141
141
|
specification_version: 4
|
142
142
|
summary: histograms data in different ways
|