quandl_operation 0.4.1 → 0.4.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rubocop.yml +19 -0
- data/Gemfile +1 -1
- data/Guardfile +3 -4
- data/Rakefile +8 -8
- data/VERSION +1 -1
- data/lib/quandl/operation.rb +6 -6
- data/lib/quandl/operation/collapse.rb +120 -116
- data/lib/quandl/operation/collapse/guess.rb +77 -83
- data/lib/quandl/operation/core_ext.rb +1 -1
- data/lib/quandl/operation/core_ext/array.rb +16 -14
- data/lib/quandl/operation/core_ext/date.rb +22 -24
- data/lib/quandl/operation/core_ext/float.rb +1 -3
- data/lib/quandl/operation/core_ext/string.rb +6 -4
- data/lib/quandl/operation/core_ext/time.rb +20 -22
- data/lib/quandl/operation/qdate.rb +14 -18
- data/lib/quandl/operation/sort.rb +24 -28
- data/lib/quandl/operation/transform.rb +145 -151
- data/lib/quandl/operation/value.rb +15 -17
- data/lib/quandl/operation/version.rb +3 -3
- data/quandl_operation.gemspec +25 -25
- data/spec/lib/quandl/operation/collapse_spec.rb +84 -77
- data/spec/lib/quandl/operation/date_spec.rb +15 -20
- data/spec/lib/quandl/operation/transform_spec.rb +15 -19
- data/spec/spec_helper.rb +4 -4
- metadata +50 -64
@@ -1,22 +1,24 @@
|
|
1
1
|
class Array
|
2
2
|
def self.forwardable_methods
|
3
|
-
[:reject, :keep_if, :to_a, :cycle, :drop, :map, :rotate, :each_slice, :pack, :select!,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
[:reject, :keep_if, :to_a, :cycle, :drop, :map, :rotate, :each_slice, :pack, :select!,
|
4
|
+
:combination, :repeated_combination, :shift, :select, :reverse!, :==, :clear, :rotate!, :inspect, :iter_for_each,
|
5
|
+
:sort_by!, :compact!, :|, :copy_data_simple, :nitems, :zip, :take, :rassoc, :flatten!, :join, :compact, :[]=,
|
6
|
+
:frozen?, :slice!, :drop_while, :reverse_each, :shuffle, :slice, :reverse, :insert, :uniq, :first, :count, :fetch,
|
7
|
+
:hash, :to_ary, :find_index, :replace, :-, :product, :iter_for_reverse_each, :pop, :push, :sort, :fill, :uniq!,
|
8
|
+
:length, :&, :flatten, :repeated_permutation, :[], :shuffle!, :sort!, :sample, :include?, :<<, :dimensions,
|
9
|
+
:collect, :+, :rindex, :<=>, :eql?, :indices, :collect!, :iter_for_each_index, :iter_for_each_with_index, :index,
|
10
|
+
:*, :indexes, :copy_data, :delete, :to_s, :assoc, :delete_at, :unshift, :delete_if, :empty?, :reject!, :last,
|
11
|
+
:size, :concat, :map!, :at, :each_index, :transpose, :values_at, :each, :enum_cons, :group_by, :enum_with_index,
|
12
|
+
:entries, :with_object, :chunk, :each_with_index, :min, :inject, :one?, :partition, :enum_slice, :none?, :max_by,
|
13
|
+
:any?, :flat_map, :reduce, :each_entry, :find, :minmax_by, :collect_concat, :each_cons, :member?, :max, :sort_by,
|
14
|
+
:detect, :all?, :minmax, :grep, :each_with_object, :find_all]
|
15
15
|
end
|
16
|
+
|
16
17
|
def average
|
17
|
-
|
18
|
+
sum / count
|
18
19
|
end
|
20
|
+
|
19
21
|
def extract_options
|
20
22
|
last.is_a?(::Hash) ? last : {}
|
21
23
|
end
|
22
|
-
end
|
24
|
+
end
|
@@ -1,55 +1,53 @@
|
|
1
1
|
class Date
|
2
|
-
|
3
2
|
def start_of_frequency(freq)
|
4
3
|
case freq.to_sym
|
5
4
|
when :daily then self
|
6
|
-
when :weekly then
|
7
|
-
when :monthly then
|
8
|
-
when :quarterly then
|
9
|
-
when :annual then
|
10
|
-
when :annually then
|
5
|
+
when :weekly then beginning_of_week
|
6
|
+
when :monthly then beginning_of_month
|
7
|
+
when :quarterly then beginning_of_quarter
|
8
|
+
when :annual then beginning_of_year
|
9
|
+
when :annually then beginning_of_year
|
11
10
|
else
|
12
11
|
self
|
13
12
|
end
|
14
13
|
end
|
15
|
-
|
14
|
+
|
16
15
|
def end_of_frequency(freq)
|
17
16
|
case freq.to_sym
|
18
17
|
when :daily then self
|
19
|
-
when :weekly then
|
20
|
-
when :monthly then
|
21
|
-
when :quarterly then
|
22
|
-
when :annual then
|
23
|
-
when :annually then
|
18
|
+
when :weekly then end_of_week
|
19
|
+
when :monthly then end_of_month
|
20
|
+
when :quarterly then end_of_quarter
|
21
|
+
when :annual then end_of_year
|
22
|
+
when :annually then end_of_year
|
24
23
|
else
|
25
24
|
self
|
26
25
|
end
|
27
26
|
end
|
28
|
-
|
29
|
-
def ranging_until(
|
27
|
+
|
28
|
+
def ranging_until(date)
|
30
29
|
self..date
|
31
30
|
end
|
32
|
-
|
33
|
-
def occurrences_of_frequency_ahead(
|
34
|
-
occurrences_of_frequency_ago(
|
31
|
+
|
32
|
+
def occurrences_of_frequency_ahead(occurrences, freq)
|
33
|
+
occurrences_of_frequency_ago(occurrences.to_i * -1, freq)
|
35
34
|
end
|
36
35
|
|
37
|
-
def occurrences_of_frequency_ago(
|
38
|
-
occurrences_of_frequency(
|
36
|
+
def occurrences_of_frequency_ago(occurrences, freq)
|
37
|
+
occurrences_of_frequency(occurrences, freq)
|
39
38
|
end
|
40
39
|
|
41
|
-
def occurrences_of_frequency(
|
40
|
+
def occurrences_of_frequency(occurrences, freq)
|
42
41
|
# ensure occurrences is an integer
|
43
42
|
occurrences = occurrences.to_i
|
44
43
|
case freq.try(:to_sym)
|
45
44
|
when :weekly then self - occurrences.weeks
|
46
45
|
when :monthly then self - occurrences.months
|
47
|
-
when :quarterly then self - (
|
46
|
+
when :quarterly then self - (occurrences * 3).months
|
48
47
|
when :annual then self - occurrences.years
|
49
48
|
when :annually then self - occurrences.years
|
50
|
-
else
|
49
|
+
else
|
51
50
|
self - occurrences
|
52
51
|
end
|
53
52
|
end
|
54
|
-
|
55
|
-
end
|
53
|
+
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
class Time
|
2
|
-
|
3
2
|
class << self
|
4
|
-
|
5
|
-
def log_elapsed(message=nil, &block)
|
3
|
+
def log_elapsed(message = nil, &block)
|
6
4
|
timer = Time.now
|
7
5
|
result = block.call
|
8
6
|
message = "#{message} (#{timer.elapsed.microseconds}ms)"
|
@@ -10,56 +8,56 @@ class Time
|
|
10
8
|
Quandl::Logger.info(message)
|
11
9
|
result
|
12
10
|
end
|
13
|
-
|
14
|
-
def elapsed(message=nil, &block)
|
11
|
+
|
12
|
+
def elapsed(message = nil, &block)
|
15
13
|
log_elapsed(message, &block)
|
16
14
|
end
|
17
|
-
|
18
15
|
end
|
19
|
-
|
16
|
+
|
20
17
|
def week_from_beginning_to_end
|
21
|
-
(
|
18
|
+
(beginning_of_week..end_of_week)
|
22
19
|
end
|
20
|
+
|
23
21
|
def this_week?
|
24
|
-
|
22
|
+
week_from_beginning_to_end.cover?(Time.now)
|
25
23
|
end
|
26
24
|
|
27
25
|
def month_from_beginning_to_end
|
28
|
-
(
|
26
|
+
(beginning_of_month..end_of_month)
|
29
27
|
end
|
28
|
+
|
30
29
|
def this_month?
|
31
|
-
|
30
|
+
month_from_beginning_to_end.cover?(Time.now)
|
32
31
|
end
|
33
32
|
|
34
33
|
def round(seconds = 60)
|
35
|
-
Time.at((
|
34
|
+
Time.at((to_f / seconds).round * seconds)
|
36
35
|
end
|
37
36
|
|
38
37
|
def floor(seconds = 60)
|
39
|
-
Time.at((
|
38
|
+
Time.at((to_f / seconds).floor * seconds)
|
40
39
|
end
|
41
|
-
|
40
|
+
|
42
41
|
def microseconds
|
43
|
-
(
|
42
|
+
(to_f * 1000.0).to_i
|
44
43
|
end
|
45
|
-
|
46
|
-
def self.elapsed(message=nil, &block)
|
44
|
+
|
45
|
+
def self.elapsed(message = nil, &block)
|
47
46
|
timer = Time.now
|
48
47
|
result = block.call
|
49
48
|
puts "#{message} (#{timer.elapsed.microseconds}ms)"
|
50
49
|
result
|
51
50
|
end
|
52
|
-
|
51
|
+
|
53
52
|
def elapsed
|
54
53
|
elapsed_since(Time.now)
|
55
54
|
end
|
56
|
-
|
55
|
+
|
57
56
|
def elapsed_since(time)
|
58
57
|
time - self
|
59
58
|
end
|
60
|
-
|
59
|
+
|
61
60
|
def elapsed_ms
|
62
61
|
"#{elapsed.microseconds}ms"
|
63
62
|
end
|
64
|
-
|
65
|
-
end
|
63
|
+
end
|
@@ -1,22 +1,18 @@
|
|
1
1
|
module Quandl
|
2
|
-
module Operation
|
3
|
-
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
2
|
+
module Operation
|
3
|
+
class QDate
|
4
|
+
class << self
|
5
|
+
def parse(value)
|
6
|
+
date = Date.jd(value.to_i) if value.is_a?(String) && value.numeric?
|
7
|
+
date = Date.jd(value) if value.is_a?(Integer)
|
8
|
+
date = Date.parse(value) if value.is_a?(String) && value =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
|
9
|
+
date = value if value.is_a?(Date)
|
10
|
+
date = value.to_date if value.respond_to?(:to_date)
|
11
|
+
date
|
12
|
+
rescue
|
13
|
+
nil
|
14
|
+
end
|
15
|
+
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
|
19
18
|
end
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
@@ -1,33 +1,29 @@
|
|
1
1
|
module Quandl
|
2
|
-
module Operation
|
3
|
-
class Sort
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
data[0][0] > data[1][0] ? :desc : :asc
|
10
|
-
end
|
11
|
-
|
12
|
-
def order(data, order = :asc)
|
13
|
-
# ascending
|
14
|
-
case order
|
15
|
-
when :asc then data = sort_asc(data)
|
16
|
-
when :desc then data = sort_desc(data)
|
17
|
-
end
|
18
|
-
data
|
19
|
-
end
|
2
|
+
module Operation
|
3
|
+
class Sort
|
4
|
+
class << self
|
5
|
+
def order?(data)
|
6
|
+
return :none if data.blank? || data[0].blank? || data[1].blank?
|
7
|
+
data[0][0] > data[1][0] ? :desc : :asc
|
8
|
+
end
|
20
9
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
10
|
+
def order(data, order = :asc)
|
11
|
+
# ascending
|
12
|
+
case order
|
13
|
+
when :asc then data = sort_asc(data)
|
14
|
+
when :desc then data = sort_desc(data)
|
15
|
+
end
|
16
|
+
data
|
17
|
+
end
|
18
|
+
|
19
|
+
def asc(data)
|
20
|
+
data.sort_by { |r| r[0] }
|
21
|
+
end
|
22
|
+
|
23
|
+
def desc(data)
|
24
|
+
data.sort_by { |r| r[0] }.reverse
|
25
|
+
end
|
26
|
+
end
|
27
27
|
end
|
28
|
-
|
29
28
|
end
|
30
|
-
|
31
|
-
end
|
32
29
|
end
|
33
|
-
end
|
@@ -1,170 +1,164 @@
|
|
1
1
|
module Quandl
|
2
|
-
module Operation
|
2
|
+
module Operation
|
3
|
+
class Transform
|
4
|
+
class << self
|
5
|
+
def perform(data, type)
|
6
|
+
assert_valid_arguments!(data, type)
|
7
|
+
# nothing to do with an empty array
|
8
|
+
return data unless data.compact.present?
|
9
|
+
# original order
|
10
|
+
order = Sort.order?(data)
|
11
|
+
# operations expect data in ascending order
|
12
|
+
data = Sort.asc(data)
|
13
|
+
# transform
|
14
|
+
data = transform(data, type)
|
15
|
+
# return to original order
|
16
|
+
data = Sort.desc(data) if order == :desc
|
17
|
+
# onwards
|
18
|
+
data = Value.precision(data, 14)
|
19
|
+
data
|
20
|
+
end
|
3
21
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def perform( data, type )
|
9
|
-
assert_valid_arguments!(data, type)
|
10
|
-
# nothing to do with an empty array
|
11
|
-
return data unless data.compact.present?
|
12
|
-
# original order
|
13
|
-
order = Sort.order?(data)
|
14
|
-
# operations expect data in ascending order
|
15
|
-
data = Sort.asc(data)
|
16
|
-
# transform
|
17
|
-
data = transform( data, type)
|
18
|
-
# return to original order
|
19
|
-
data = Sort.desc(data) if order == :desc
|
20
|
-
# onwards
|
21
|
-
data = Value.precision(data, 14)
|
22
|
-
data
|
23
|
-
end
|
24
|
-
|
25
|
-
def assert_valid_arguments!(data, type)
|
26
|
-
raise ArgumentError, "data must be an Array. Received: #{data.class}" unless data.is_a?(Array)
|
27
|
-
raise ArgumentError, "frequency must be one of #{valid_transformations}. Received: #{type}" unless valid?(type)
|
28
|
-
end
|
29
|
-
|
30
|
-
def valid_transformation?(type)
|
31
|
-
valid?(type)
|
32
|
-
end
|
33
|
-
|
34
|
-
def valid?(type)
|
35
|
-
valid_transformations.include?( type.try(:to_sym) )
|
36
|
-
end
|
37
|
-
|
38
|
-
def valid_transformations
|
39
|
-
[ :diff, :rdiff, :cumul, :normalize, :rdiff_from ]
|
40
|
-
end
|
41
|
-
|
42
|
-
def transform( data, type)
|
43
|
-
return data if data.blank?
|
44
|
-
#Transforms table from actual data points
|
45
|
-
#to differences between points (:diff)
|
46
|
-
#or a ratio between points(:rdiff)
|
47
|
-
#or a ratio between the latest point and an earlier point (:rdiff_from)
|
48
|
-
#If type is other than these two, nothing is done.
|
49
|
-
|
50
|
-
# ensure that type is in the expected format
|
51
|
-
type = type.try(:to_sym)
|
52
|
-
# nothing to do unless valid transform
|
53
|
-
return data unless valid_transformation?( type )
|
54
|
-
|
55
|
-
temparr = Array.new
|
56
|
-
#first make a keylist
|
57
|
-
keylist = data.transpose.first
|
58
|
-
# now sort the keylist from oldest to newest
|
59
|
-
# unless there is only one point
|
60
|
-
if keylist.count > 1
|
61
|
-
keylist = keylist.reverse if keylist[0] > keylist[1] # better performance if we do this first
|
62
|
-
keylist.sort!
|
63
|
-
end
|
22
|
+
def assert_valid_arguments!(data, type)
|
23
|
+
fail ArgumentError, "data must be an Array. Received: #{data.class}" unless data.is_a?(Array)
|
24
|
+
fail ArgumentError, "frequency must be one of #{valid_transformations}. Received: #{type}" unless valid?(type)
|
25
|
+
end
|
64
26
|
|
65
|
-
|
66
|
-
|
67
|
-
if type == :normalize
|
68
|
-
divisor = Array.new(numcols,nil)
|
69
|
-
0.upto(keylist.length - 1) do |i|
|
70
|
-
temparr[i] = []
|
71
|
-
curr_row = data[i][1..-1]
|
72
|
-
0.upto(numcols-1) do |x|
|
73
|
-
if curr_row[x].nil?
|
74
|
-
temparr[i][x] = nil
|
75
|
-
elsif divisor[x].nil?
|
76
|
-
if curr_row[x].to_f != 0
|
77
|
-
divisor[x] = curr_row[x].to_f
|
78
|
-
temparr[i][x] = 100.0
|
79
|
-
else
|
80
|
-
temparr[i][x] = 0
|
81
|
-
end
|
82
|
-
else
|
83
|
-
temparr[i][x] = curr_row[x] / divisor[x] * 100.0
|
84
|
-
end
|
85
|
-
end
|
27
|
+
def valid_transformation?(type)
|
28
|
+
valid?(type)
|
86
29
|
end
|
87
|
-
|
88
|
-
|
30
|
+
|
31
|
+
def valid?(type)
|
32
|
+
valid_transformations.include?(type.try(:to_sym))
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_transformations
|
36
|
+
[:diff, :rdiff, :cumul, :normalize, :rdiff_from]
|
89
37
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
38
|
+
|
39
|
+
def transform(data, type)
|
40
|
+
return data if data.blank?
|
41
|
+
# Transforms table from actual data points
|
42
|
+
# to differences between points (:diff)
|
43
|
+
# or a ratio between points(:rdiff)
|
44
|
+
# or a ratio between the latest point and an earlier point (:rdiff_from)
|
45
|
+
# If type is other than these two, nothing is done.
|
46
|
+
|
47
|
+
# ensure that type is in the expected format
|
48
|
+
type = type.try(:to_sym)
|
49
|
+
# nothing to do unless valid transform
|
50
|
+
return data unless valid_transformation?(type)
|
51
|
+
|
52
|
+
temparr = []
|
53
|
+
# first make a keylist
|
54
|
+
keylist = data.transpose.first
|
55
|
+
# now sort the keylist from oldest to newest
|
56
|
+
# unless there is only one point
|
57
|
+
if keylist.count > 1
|
58
|
+
keylist = keylist.reverse if keylist[0] > keylist[1] # better performance if we do this first
|
59
|
+
keylist.sort!
|
60
|
+
end
|
61
|
+
|
62
|
+
# find number of columns
|
63
|
+
numcols = data.first.size - 1
|
64
|
+
if type == :normalize
|
65
|
+
divisor = Array.new(numcols, nil)
|
66
|
+
0.upto(keylist.length - 1) do |i|
|
67
|
+
temparr[i] = []
|
68
|
+
curr_row = data[i][1..-1]
|
69
|
+
0.upto(numcols - 1) do |x|
|
70
|
+
if curr_row[x].nil?
|
71
|
+
temparr[i][x] = nil
|
72
|
+
elsif divisor[x].nil?
|
73
|
+
if curr_row[x].to_f != 0
|
74
|
+
divisor[x] = curr_row[x].to_f
|
75
|
+
temparr[i][x] = 100.0
|
76
|
+
else
|
77
|
+
temparr[i][x] = 0
|
78
|
+
end
|
79
|
+
else
|
80
|
+
temparr[i][x] = curr_row[x] / divisor[x] * 100.0
|
81
|
+
end
|
102
82
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
83
|
+
end
|
84
|
+
0.upto(keylist.length - 1) do |i|
|
85
|
+
data[i] = [keylist[i], temparr[i]].flatten
|
86
|
+
end
|
87
|
+
elsif [:diff, :rdiff].include? type
|
88
|
+
# now build temparr
|
89
|
+
1.upto(keylist.length - 1) do |i|
|
90
|
+
temparr[i] = []
|
91
|
+
curr_row = data[i][1..-1]
|
92
|
+
prev_row = data[i - 1][1..-1]
|
93
|
+
0.upto(numcols - 1) do |x|
|
94
|
+
if type == :diff
|
95
|
+
if !curr_row[x].nil? && !prev_row[x].nil?
|
96
|
+
temparr[i][x] = Float(curr_row[x]) - Float(prev_row[x])
|
97
|
+
else
|
98
|
+
temparr[i][x] = nil
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if !curr_row[x].nil? && !prev_row[x].nil? && prev_row[x] != 0
|
102
|
+
temparr[i][x] = (Float(curr_row[x]) - Float(prev_row[x])) / Float(prev_row[x])
|
103
|
+
else
|
104
|
+
temparr[i][x] = nil
|
105
|
+
end
|
106
|
+
end
|
108
107
|
end
|
109
108
|
end
|
110
|
-
end
|
111
|
-
end
|
112
109
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
#delete the first date in datapac (because there is no diff for that)
|
119
|
-
data.delete_at(0)
|
120
|
-
elsif type == :rdiff_from
|
121
|
-
num_rows = keylist.length - 1
|
122
|
-
initial = Array.new(numcols,nil)
|
123
|
-
num_rows.downto(0) do |i|
|
124
|
-
temparr[i] = []
|
125
|
-
curr_row = data[i][1..-1]
|
126
|
-
0.upto(numcols-1) do |x|
|
127
|
-
if curr_row[x].nil?
|
128
|
-
temparr[i][x] = nil
|
129
|
-
elsif initial[x].nil?
|
130
|
-
initial[x] = curr_row[x]
|
131
|
-
temparr[i][x] = 0.0
|
132
|
-
elsif curr_row[x] == 0
|
133
|
-
temparr[i][x] = nil
|
134
|
-
else
|
135
|
-
temparr[i][x] = ( Float(initial[x]) - Float(curr_row[x]) ) / Float(curr_row[x])
|
110
|
+
# now put temparr into datapac
|
111
|
+
1.upto(keylist.length - 1) do |i|
|
112
|
+
data[i] = [keylist[i], temparr[i]].flatten
|
136
113
|
end
|
137
|
-
end
|
138
|
-
end
|
139
114
|
|
115
|
+
# delete the first date in datapac (because there is no diff for that)
|
116
|
+
data.delete_at(0)
|
117
|
+
elsif type == :rdiff_from
|
118
|
+
num_rows = keylist.length - 1
|
119
|
+
initial = Array.new(numcols, nil)
|
120
|
+
num_rows.downto(0) do |i|
|
121
|
+
temparr[i] = []
|
122
|
+
curr_row = data[i][1..-1]
|
123
|
+
0.upto(numcols - 1) do |x|
|
124
|
+
if curr_row[x].nil?
|
125
|
+
temparr[i][x] = nil
|
126
|
+
elsif initial[x].nil?
|
127
|
+
initial[x] = curr_row[x]
|
128
|
+
temparr[i][x] = 0.0
|
129
|
+
elsif curr_row[x] == 0
|
130
|
+
temparr[i][x] = nil
|
131
|
+
else
|
132
|
+
temparr[i][x] = (Float(initial[x]) - Float(curr_row[x])) / Float(curr_row[x])
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
140
136
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
137
|
+
0.upto(keylist.length - 1) do |i|
|
138
|
+
data[i] = [keylist[i], temparr[i]].flatten
|
139
|
+
end
|
140
|
+
else
|
141
|
+
cumulsum = Array.new(numcols, 0)
|
142
|
+
sumstarted = Array.new(numcols, false)
|
143
|
+
# now build temparr
|
144
|
+
0.upto(keylist.length - 1) do |i|
|
145
|
+
temparr[i] = []
|
146
|
+
curr_row = data[i][1..-1]
|
147
|
+
0.upto(numcols - 1) do |x|
|
148
|
+
unless curr_row[x].nil?
|
149
|
+
cumulsum[x] = cumulsum[x] + curr_row[x]
|
150
|
+
sumstarted[x] = true
|
151
|
+
end
|
152
|
+
temparr[i][x] = cumulsum[x] if sumstarted[x]
|
153
|
+
end
|
154
|
+
end
|
155
|
+
0.upto(keylist.length - 1) do |i|
|
156
|
+
data[i] = [keylist[i], temparr[i]].flatten
|
155
157
|
end
|
156
|
-
temparr[i][x] = cumulsum[x] if sumstarted[x]
|
157
158
|
end
|
158
|
-
|
159
|
-
0.upto(keylist.length-1) do |i|
|
160
|
-
data[i] = [keylist[i],temparr[i]].flatten
|
159
|
+
data
|
161
160
|
end
|
162
161
|
end
|
163
|
-
data
|
164
162
|
end
|
165
|
-
|
166
163
|
end
|
167
|
-
|
168
|
-
end
|
169
164
|
end
|
170
|
-
end
|