quandl_operation 0.4.1 → 0.4.2.rc1
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 +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
|