jsvd-sequel_vectorized 0.0.3 → 0.0.5
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.
- data/ChangeLog +10 -0
- data/lib/sequel_vectorized.rb +67 -2
- data/sequel_vectorized.gemspec +1 -1
- data/spec/sequel_vectorized_spec.rb +101 -0
- metadata +6 -3
data/ChangeLog
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.0.5 / 2009-06-04
|
2
|
+
|
3
|
+
* Axis range is now a ruby Range
|
4
|
+
* Proper creation of data vectors if end of range is excluded or not
|
5
|
+
|
6
|
+
== 0.0.4 / 2009-06-04
|
7
|
+
|
8
|
+
* Now returns empty hash if result set is empty even if axis is passed
|
9
|
+
* Added original data and raw mask to data array
|
10
|
+
|
1
11
|
== 0.0.3 / 2009-01-28
|
2
12
|
|
3
13
|
* No longer has module Sequel::Plugins::Vectorized
|
data/lib/sequel_vectorized.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
require 'narray'
|
2
|
+
require 'gsl'
|
2
3
|
|
3
4
|
class Sequel::Dataset
|
4
|
-
def vectorize
|
5
|
+
def vectorize options={}
|
5
6
|
|
6
7
|
result = {}
|
8
|
+
axis = (options[:axis] ||= {})
|
7
9
|
|
8
10
|
# transform dataset to hash of arrays
|
9
|
-
|
11
|
+
dataset = filter(axis[:column] => axis[:range])
|
12
|
+
|
13
|
+
dataset.map {|row| row.each{|att,value| (result[att] ||= []) << value}}
|
10
14
|
|
11
15
|
# transform numeric and boolean arrays to narrays
|
12
16
|
result.each do |k,v|
|
@@ -24,6 +28,67 @@ class Sequel::Dataset
|
|
24
28
|
result[k][] = v.map {|i| (i == true) ? 1 : 0 }
|
25
29
|
|
26
30
|
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
# add dot notation
|
35
|
+
columns.each do |col|
|
36
|
+
result.instance_eval %Q{def #{col}; self[:#{col}]; end}
|
37
|
+
end
|
38
|
+
|
39
|
+
if (axis.empty? || result.empty?) then
|
40
|
+
result
|
41
|
+
else
|
42
|
+
_process(result, axis)
|
27
43
|
end
|
44
|
+
|
28
45
|
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def _process data, axis
|
49
|
+
axis_col = axis[:column]
|
50
|
+
step = axis[:step]
|
51
|
+
range = axis[:range]
|
52
|
+
interpolate = axis[:interpolate]
|
53
|
+
|
54
|
+
new_size = (range.last - range.first)/step.to_f
|
55
|
+
new_size +=1 unless range.exclude_end?
|
56
|
+
raw_axis = data[axis_col]
|
57
|
+
data["__#{axis_col}".to_sym] = raw_axis
|
58
|
+
|
59
|
+
interp = GSL::Interp.alloc("linear", raw_axis.size) if interpolate
|
60
|
+
|
61
|
+
data[axis_col] = NArray.float(new_size).indgen!(range.first,step)
|
62
|
+
|
63
|
+
data[:__raw_mask] = NArray.byte(new_size)
|
64
|
+
data[:__raw_mask][(raw_axis - range.first)/step.to_f] = 1
|
65
|
+
|
66
|
+
data.keys.each do |k|
|
67
|
+
|
68
|
+
next if (k == axis_col || k == "__#{axis_col}".to_sym)
|
69
|
+
|
70
|
+
v = data[k]
|
71
|
+
|
72
|
+
# if first is a float, vector is a NArray and will be interpolated
|
73
|
+
if v[0].is_a? Float then
|
74
|
+
data["__#{k}".to_sym] = v #backup data in :__key
|
75
|
+
if interpolate
|
76
|
+
# problem with GSL lack of NArray support on compilation
|
77
|
+
raw_axis_vector = GSL::Vector[raw_axis.to_a]
|
78
|
+
v_vector = GSL::Vector[v.to_a]
|
79
|
+
data_vector = GSL::Vector[data[axis_col].to_a]
|
80
|
+
|
81
|
+
data[k] = interp.init(raw_axis_vector, v_vector)
|
82
|
+
data[k] = NArray.to_na data[k].eval(raw_axis_vector, v_vector, data_vector).to_a
|
83
|
+
else
|
84
|
+
data[k] = NArray.float(new_size)
|
85
|
+
data[k][(raw_axis - range.first)/step.to_f] = v
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
data
|
91
|
+
|
92
|
+
end
|
93
|
+
|
29
94
|
end
|
data/sequel_vectorized.gemspec
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'spec'
|
2
3
|
require 'sequel'
|
3
4
|
|
@@ -72,4 +73,104 @@ describe Sequel::Dataset do
|
|
72
73
|
}
|
73
74
|
end
|
74
75
|
|
76
|
+
it "is possible to pass an :axis option" do
|
77
|
+
axis = {
|
78
|
+
:column => :ts,
|
79
|
+
:step => 60,
|
80
|
+
:range => Time.local(2008,1,1,12).to_f ... Time.local(2008,1,1,15).to_f,
|
81
|
+
:interpolate => true
|
82
|
+
}
|
83
|
+
|
84
|
+
lambda {
|
85
|
+
@events.vectorize axis
|
86
|
+
}.should_not raise_error
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns new narrays of size (range.last-range.first)/step if :axis is given" do
|
90
|
+
|
91
|
+
axis = {
|
92
|
+
:column => :ts,
|
93
|
+
:step => 60,
|
94
|
+
:range => Time.local(2008,1,1,12).to_f ... Time.local(2008,1,1,15).to_f,
|
95
|
+
:interpolate => false
|
96
|
+
}
|
97
|
+
|
98
|
+
ret = @events.vectorize :axis => axis
|
99
|
+
|
100
|
+
new_ret = ret.delete_if {|k,v| k.to_s.match(/__\w+/) }
|
101
|
+
|
102
|
+
new_ret.should == {
|
103
|
+
:value => NArray.to_na([[0]*30, 2.2, [0]*59, 1.1, [0]*59,3.3, [0]*29].flatten),
|
104
|
+
:ts => NArray.float(180).indgen(Time.local(2008,1,1,12).to_f,60)
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
it "interpolates NArrays if :axis option :interpolate is true" do
|
109
|
+
# TODO: not spec'ed
|
110
|
+
axis = {
|
111
|
+
:column => :ts,
|
112
|
+
:step => 60,
|
113
|
+
:range => Time.local(2008,1,1,12).to_f ... Time.local(2008,1,1,15).to_f,
|
114
|
+
:interpolate => true
|
115
|
+
}
|
116
|
+
|
117
|
+
ret = @events.vectorize :axis => axis
|
118
|
+
|
119
|
+
ret[:ts].should == NArray.float(180).indgen(Time.local(2008,1,1,12).to_f,60)
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
it "returns a vectorized result set that inherits from Hash and has dot notation" do
|
125
|
+
|
126
|
+
axis = {
|
127
|
+
:column => :ts,
|
128
|
+
:step => 60,
|
129
|
+
:range => Time.local(2008,1,1,12).to_f ... Time.local(2008,1,1,15).to_f,
|
130
|
+
:interpolate => false
|
131
|
+
}
|
132
|
+
|
133
|
+
ret = @events.vectorize :axis => axis
|
134
|
+
|
135
|
+
ret.should be_a_kind_of Hash
|
136
|
+
|
137
|
+
ret.should respond_to :ts
|
138
|
+
ret.should respond_to :value
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should be empty if there is no data" do
|
143
|
+
@items.filter(:name => 'be').vectorize.should be_empty
|
144
|
+
@items.filter(:name => 'be').vectorize(:axis => {:column => :price, :range => 0 ... 100, :step => 20 }).should be_empty
|
145
|
+
@items.filter(:name => 'abc').vectorize(:axis => {:column => :price, :range => 0 ... 100, :step => 20 }).should_not be_empty
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should not raise error for an interval" do
|
149
|
+
|
150
|
+
require 'lib/sequel_vectorized'
|
151
|
+
|
152
|
+
@events << {:value => 2.2, :ts => Time.local(2009,8,14,21,0).to_f}
|
153
|
+
@events << {:value => 2.2, :ts => Time.local(2009,8,14,22,0).to_f}
|
154
|
+
@events << {:value => 1.1, :ts => Time.local(2009,8,14,23,20).to_f}
|
155
|
+
@events << {:value => 3.3, :ts => Time.local(2009,8,15,0).to_f}
|
156
|
+
@events << {:value => 3.3, :ts => Time.local(2009,8,15,1).to_f}
|
157
|
+
|
158
|
+
axis = {
|
159
|
+
:column => :ts,
|
160
|
+
:step => 60,
|
161
|
+
:range => Time.local(2009,8,14,22).to_f .. Time.local(2009,8,15,0).to_f,
|
162
|
+
:interpolate => false
|
163
|
+
}
|
164
|
+
|
165
|
+
lambda { @events.vectorize :axis => axis }.should_not raise_error
|
166
|
+
axis[:interpolate] = true
|
167
|
+
lambda { @events.vectorize :axis => axis }.should_not raise_error
|
168
|
+
|
169
|
+
axis[:range] = Time.local(2009,8,14,22).to_f .. Time.local(2009,8,15,0).to_f
|
170
|
+
|
171
|
+
lambda { @events.vectorize :axis => axis }.should_not raise_error
|
172
|
+
axis[:interpolate] = false
|
173
|
+
lambda { @events.vectorize :axis => axis }.should_not raise_error
|
174
|
+
|
175
|
+
end
|
75
176
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jsvd-sequel_vectorized
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jo\xC3\xA3o Duarte"
|
@@ -9,11 +9,12 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-16 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: sequel
|
17
|
+
type: :runtime
|
17
18
|
version_requirement:
|
18
19
|
version_requirements: !ruby/object:Gem::Requirement
|
19
20
|
requirements:
|
@@ -23,6 +24,7 @@ dependencies:
|
|
23
24
|
version:
|
24
25
|
- !ruby/object:Gem::Dependency
|
25
26
|
name: narray
|
27
|
+
type: :runtime
|
26
28
|
version_requirement:
|
27
29
|
version_requirements: !ruby/object:Gem::Requirement
|
28
30
|
requirements:
|
@@ -46,6 +48,7 @@ files:
|
|
46
48
|
- ChangeLog
|
47
49
|
has_rdoc: false
|
48
50
|
homepage:
|
51
|
+
licenses:
|
49
52
|
post_install_message:
|
50
53
|
rdoc_options: []
|
51
54
|
|
@@ -66,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
66
69
|
requirements: []
|
67
70
|
|
68
71
|
rubyforge_project:
|
69
|
-
rubygems_version: 1.
|
72
|
+
rubygems_version: 1.3.5
|
70
73
|
signing_key:
|
71
74
|
specification_version: 2
|
72
75
|
summary: ""
|