daru 0.1.3.1 → 0.1.4
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/.gitignore +2 -0
- data/.rspec +2 -1
- data/.rspec_formatter.rb +33 -0
- data/.rubocop.yml +26 -2
- data/History.md +38 -0
- data/README.md +22 -13
- data/Rakefile +50 -2
- data/benchmarks/csv_reading.rb +22 -0
- data/daru.gemspec +9 -2
- data/lib/daru.rb +36 -4
- data/lib/daru/accessors/array_wrapper.rb +6 -1
- data/lib/daru/accessors/dataframe_by_row.rb +10 -2
- data/lib/daru/accessors/gsl_wrapper.rb +1 -3
- data/lib/daru/accessors/nmatrix_wrapper.rb +9 -0
- data/lib/daru/category.rb +935 -0
- data/lib/daru/core/group_by.rb +29 -38
- data/lib/daru/core/merge.rb +186 -145
- data/lib/daru/core/query.rb +22 -11
- data/lib/daru/dataframe.rb +976 -885
- data/lib/daru/date_time/index.rb +166 -166
- data/lib/daru/date_time/offsets.rb +66 -77
- data/lib/daru/formatters/table.rb +54 -0
- data/lib/daru/helpers/array.rb +40 -0
- data/lib/daru/index.rb +476 -73
- data/lib/daru/io/io.rb +66 -45
- data/lib/daru/io/sql_data_source.rb +33 -62
- data/lib/daru/iruby/helpers.rb +38 -0
- data/lib/daru/iruby/templates/dataframe.html.erb +52 -0
- data/lib/daru/iruby/templates/dataframe_mi.html.erb +58 -0
- data/lib/daru/iruby/templates/multi_index.html.erb +12 -0
- data/lib/daru/iruby/templates/vector.html.erb +27 -0
- data/lib/daru/iruby/templates/vector_mi.html.erb +36 -0
- data/lib/daru/maths/arithmetic/dataframe.rb +16 -18
- data/lib/daru/maths/arithmetic/vector.rb +4 -6
- data/lib/daru/maths/statistics/dataframe.rb +8 -15
- data/lib/daru/maths/statistics/vector.rb +120 -98
- data/lib/daru/monkeys.rb +12 -40
- data/lib/daru/plotting/gruff.rb +3 -0
- data/lib/daru/plotting/gruff/category.rb +49 -0
- data/lib/daru/plotting/gruff/dataframe.rb +91 -0
- data/lib/daru/plotting/gruff/vector.rb +57 -0
- data/lib/daru/plotting/nyaplot.rb +3 -0
- data/lib/daru/plotting/nyaplot/category.rb +34 -0
- data/lib/daru/plotting/nyaplot/dataframe.rb +187 -0
- data/lib/daru/plotting/nyaplot/vector.rb +46 -0
- data/lib/daru/vector.rb +694 -421
- data/lib/daru/version.rb +1 -1
- data/profile/_base.rb +23 -0
- data/profile/df_to_a.rb +10 -0
- data/profile/filter.rb +13 -0
- data/profile/joining.rb +13 -0
- data/profile/sorting.rb +12 -0
- data/profile/vector_each_with_index.rb +9 -0
- data/spec/accessors/wrappers_spec.rb +2 -4
- data/spec/categorical_spec.rb +1734 -0
- data/spec/core/group_by_spec.rb +52 -2
- data/spec/core/merge_spec.rb +63 -2
- data/spec/core/query_spec.rb +236 -80
- data/spec/dataframe_spec.rb +1373 -79
- data/spec/date_time/data_spec.rb +3 -5
- data/spec/date_time/index_spec.rb +154 -17
- data/spec/date_time/offsets_spec.rb +3 -4
- data/spec/fixtures/empties.dat +2 -0
- data/spec/fixtures/strings.dat +2 -0
- data/spec/formatters/table_formatter_spec.rb +99 -0
- data/spec/helpers_spec.rb +8 -0
- data/spec/index/categorical_index_spec.rb +168 -0
- data/spec/index/index_spec.rb +283 -0
- data/spec/index/multi_index_spec.rb +570 -0
- data/spec/io/io_spec.rb +31 -4
- data/spec/io/sql_data_source_spec.rb +0 -1
- data/spec/iruby/dataframe_spec.rb +172 -0
- data/spec/iruby/helpers_spec.rb +49 -0
- data/spec/iruby/multi_index_spec.rb +37 -0
- data/spec/iruby/vector_spec.rb +107 -0
- data/spec/math/arithmetic/dataframe_spec.rb +71 -13
- data/spec/math/arithmetic/vector_spec.rb +8 -10
- data/spec/math/statistics/dataframe_spec.rb +3 -5
- data/spec/math/statistics/vector_spec.rb +45 -55
- data/spec/monkeys_spec.rb +32 -9
- data/spec/plotting/dataframe_spec.rb +386 -0
- data/spec/plotting/vector_spec.rb +230 -0
- data/spec/shared/vector_display_spec.rb +215 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/vector_spec.rb +905 -138
- metadata +143 -11
- data/.rubocop_todo.yml +0 -44
- data/lib/daru/plotting/dataframe.rb +0 -104
- data/lib/daru/plotting/vector.rb +0 -38
- data/spec/daru_spec.rb +0 -58
- data/spec/index_spec.rb +0 -375
data/spec/core/group_by_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'spec_helper.rb'
|
2
|
-
|
3
1
|
describe Daru::Core::GroupBy do
|
4
2
|
before do
|
5
3
|
@df = Daru::DataFrame.new({
|
@@ -140,6 +138,44 @@ describe Daru::Core::GroupBy do
|
|
140
138
|
end
|
141
139
|
end
|
142
140
|
|
141
|
+
context '#each_group' do
|
142
|
+
it 'enumerates groups' do
|
143
|
+
ret = []
|
144
|
+
@dl_group.each_group { |g| ret << g }
|
145
|
+
expect(ret.count).to eq 6
|
146
|
+
expect(ret).to all be_a(Daru::DataFrame)
|
147
|
+
expect(ret.first).to eq(Daru::DataFrame.new({
|
148
|
+
a: ['bar'],
|
149
|
+
b: ['one'],
|
150
|
+
c: [2],
|
151
|
+
d: [22]
|
152
|
+
}, index: [1]
|
153
|
+
))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context '#first' do
|
158
|
+
it 'gets the first row from each group' do
|
159
|
+
expect(@dl_group.first).to eq(Daru::DataFrame.new({
|
160
|
+
a: %w{bar bar bar foo foo foo },
|
161
|
+
b: %w{one three two one three two },
|
162
|
+
c: [2 ,1 ,6 ,1 ,8 ,3 ],
|
163
|
+
d: [22 ,44 ,66 ,11 ,88 ,33 ]
|
164
|
+
}, index: [1,3,5,0,7,2]))
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context '#last' do
|
169
|
+
it 'gets the last row from each group' do
|
170
|
+
expect(@dl_group.last).to eq(Daru::DataFrame.new({
|
171
|
+
a: %w{bar bar bar foo foo foo },
|
172
|
+
b: %w{one three two one three two },
|
173
|
+
c: [2 ,1 ,6 ,3 ,8 ,3 ],
|
174
|
+
d: [22 ,44 ,66 ,77 ,88 ,55 ]
|
175
|
+
}, index: [1,3,5,6,7,4]))
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
143
179
|
context "#aggregate" do
|
144
180
|
pending
|
145
181
|
end
|
@@ -191,6 +227,14 @@ describe Daru::Core::GroupBy do
|
|
191
227
|
end
|
192
228
|
end
|
193
229
|
|
230
|
+
[:median, :std, :max, :min].each do |numeric_method|
|
231
|
+
it "works somehow" do
|
232
|
+
expect(@sl_group.send(numeric_method).index).to eq @sl_index
|
233
|
+
expect(@dl_group.send(numeric_method).index).to eq @dl_multi_index
|
234
|
+
expect(@tl_group.send(numeric_method).index).to eq @tl_multi_index
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
194
238
|
context "#product" do
|
195
239
|
it "calculates product for single layer groups" do
|
196
240
|
# TODO
|
@@ -351,5 +395,11 @@ describe Daru::Core::GroupBy do
|
|
351
395
|
string_concat = lambda { |result, row| result += row[:b] }
|
352
396
|
expect(@sl_group.reduce('', &string_concat)).to eq(Daru::Vector.new(['onethreetwo', 'onetwotwoonethree'], index: @sl_index))
|
353
397
|
end
|
398
|
+
|
399
|
+
it "works with multi-indexes" do
|
400
|
+
string_concat = lambda { |result, row| result += row[:b] }
|
401
|
+
expect(@dl_group.reduce('', &string_concat)).to eq \
|
402
|
+
Daru::Vector.new(['one', 'three', 'two', 'oneone', 'three', 'twotwo'], index: @dl_multi_index)
|
403
|
+
end
|
354
404
|
end
|
355
405
|
end
|
data/spec/core/merge_spec.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe Daru::DataFrame do
|
4
2
|
context "#join" do
|
5
3
|
before do
|
@@ -39,6 +37,16 @@ describe Daru::DataFrame do
|
|
39
37
|
expect(@left.join(@right_many, how: :inner, on: [:id])).to eq(answer)
|
40
38
|
end
|
41
39
|
|
40
|
+
it "performs an inner join of two dataframes that has many to many mapping" do
|
41
|
+
@left[:id].recode! { |v| v == 2 ? 1 : v }
|
42
|
+
answer = Daru::DataFrame.new({
|
43
|
+
:name_1 => ['Pirate', 'Pirate', 'Pirate', 'Pirate', 'Monkey', 'Monkey', 'Monkey', 'Monkey'],
|
44
|
+
:id => [1,1,1,1,1,1,1,1],
|
45
|
+
:name_2 => ['Rutabaga', 'Pirate', 'Darth Vader', 'Ninja', 'Rutabaga', 'Pirate', 'Darth Vader', 'Ninja']
|
46
|
+
}, order: [:name_1, :id, :name_2])
|
47
|
+
expect(@left.join(@right_many, how: :inner, on: [:id])).to eq(answer)
|
48
|
+
end
|
49
|
+
|
42
50
|
it "performs a full outer join" do
|
43
51
|
answer = Daru::DataFrame.new({
|
44
52
|
:id_1 => [nil,2,3,1,nil,4],
|
@@ -48,6 +56,38 @@ describe Daru::DataFrame do
|
|
48
56
|
expect(@left.join(@right, how: :outer, on: [:name])).to eq(answer)
|
49
57
|
end
|
50
58
|
|
59
|
+
it "performs a full outer join when the right join keys have nils" do
|
60
|
+
@right[:name].recode! { |v| v == 'Rutabaga' ? nil : v }
|
61
|
+
answer = Daru::DataFrame.new({
|
62
|
+
:id_1 => [nil, nil,2,3,1,4],
|
63
|
+
:name => [nil, "Darth Vader", "Monkey", "Ninja", "Pirate", "Spaghetti"],
|
64
|
+
:id_2 => [1,3,nil,4,2,nil]
|
65
|
+
}, order: [:id_1, :name, :id_2])
|
66
|
+
expect(@left.join(@right, how: :outer, on: [:name])).to eq(answer)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "performs a full outer join when the left join keys have nils" do
|
70
|
+
@left[:name].recode! { |v| v == 'Monkey' ? nil : v }
|
71
|
+
answer = Daru::DataFrame.new({
|
72
|
+
:id_1 => [2,nil,3,1,nil,4],
|
73
|
+
:name => [nil, "Darth Vader", "Ninja", "Pirate", "Rutabaga", "Spaghetti"],
|
74
|
+
:id_2 => [nil,3,4,2,1,nil]
|
75
|
+
}, order: [:id_1, :name, :id_2])
|
76
|
+
expect(@left.join(@right, how: :outer, on: [:name])).to eq(answer)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "performs a full outer join when both left and right join keys have nils" do
|
80
|
+
@left[:name].recode! { |v| v == 'Monkey' ? nil : v }
|
81
|
+
@right[:name].recode! { |v| v == 'Rutabaga' ? nil : v }
|
82
|
+
|
83
|
+
answer = Daru::DataFrame.new({
|
84
|
+
:id_1 => [nil,2,nil,3,1,4],
|
85
|
+
:name => [nil, nil, "Darth Vader", "Ninja", "Pirate", "Spaghetti"],
|
86
|
+
:id_2 => [1,nil,3,4,2,nil]
|
87
|
+
}, order: [:id_1, :name, :id_2])
|
88
|
+
expect(@left.join(@right, how: :outer, on: [:name])).to eq(answer)
|
89
|
+
end
|
90
|
+
|
51
91
|
it "performs a left outer join", focus: true do
|
52
92
|
answer = Daru::DataFrame.new({
|
53
93
|
:id_1 => [2,3,1,4],
|
@@ -77,5 +117,26 @@ describe Daru::DataFrame do
|
|
77
117
|
expect(@left.join(@right, how: :right, on: [:name])).to eq(answer)
|
78
118
|
end
|
79
119
|
|
120
|
+
it "raises if :on field are absent in one of dataframes" do
|
121
|
+
@right.vectors = [:id, :other_name]
|
122
|
+
expect { @left.join(@right, how: :right, on: [:name]) }.to \
|
123
|
+
raise_error(ArgumentError, /Both dataframes expected .* :name/)
|
124
|
+
|
125
|
+
expect { @left.join(@right, how: :right, on: [:other_name]) }.to \
|
126
|
+
raise_error(ArgumentError, /Both dataframes expected .* :other_name/)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "is able to join by several :on fields" do
|
130
|
+
@left.gender = ['m', 'f', 'm', nil]
|
131
|
+
@right.gender = ['m', 'm', nil, 'f']
|
132
|
+
|
133
|
+
answer = Daru::DataFrame.new({
|
134
|
+
id_1: [1],
|
135
|
+
name: ['Pirate'],
|
136
|
+
gender: ['m'],
|
137
|
+
id_2: [2]
|
138
|
+
}, order: [:id_1, :name, :gender, :id_2])
|
139
|
+
expect(@left.join(@right, how: :inner, on: [:name, :gender])).to eq(answer)
|
140
|
+
end
|
80
141
|
end
|
81
142
|
end
|
data/spec/core/query_spec.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
1
|
describe Daru::Core::Query::BoolArray do
|
4
2
|
before do
|
5
|
-
@klass = Daru::Core::Query::BoolArray
|
3
|
+
@klass = Daru::Core::Query::BoolArray
|
6
4
|
@left = @klass.new([true, true, true, false, false, true])
|
7
5
|
@right = @klass.new([false, false, false, false, true, false])
|
8
6
|
end
|
@@ -28,94 +26,212 @@ describe Daru::Core::Query::BoolArray do
|
|
28
26
|
)
|
29
27
|
end
|
30
28
|
end
|
29
|
+
|
30
|
+
context '#inspect' do
|
31
|
+
it 'is reasonable' do
|
32
|
+
expect(@left.inspect).to eq "#<Daru::Core::Query::BoolArray:#{@left.object_id} bool_arry=[true, true, true, false, false, true]>"
|
33
|
+
end
|
34
|
+
end
|
31
35
|
end
|
32
36
|
|
33
37
|
describe "Arel-like syntax" do
|
34
38
|
describe "comparison operators" do
|
35
39
|
describe Daru::Vector do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
context "#eq" do
|
43
|
-
it "accepts scalar value" do
|
44
|
-
expect(@vector.eq(352)).to eq(
|
45
|
-
@klass.new([false,false,false,true,false,false]))
|
40
|
+
describe "non-categorical type" do
|
41
|
+
before do
|
42
|
+
@vector = Daru::Vector.new([23,51,1214,352,32,11])
|
43
|
+
@comparator = Daru::Vector.new([45,22,1214,55,32,9])
|
44
|
+
@klass = Daru::Core::Query::BoolArray
|
46
45
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@
|
46
|
+
|
47
|
+
context "#eq" do
|
48
|
+
it "accepts scalar value" do
|
49
|
+
expect(@vector.eq(352)).to eq(
|
50
|
+
@klass.new([false,false,false,true,false,false]))
|
51
|
+
end
|
52
|
+
|
53
|
+
it "accepts vector and compares corrensponding elements" do
|
54
|
+
expect(@vector.eq(@comparator)).to eq(
|
55
|
+
@klass.new([false,false,true,false,true,false]))
|
56
|
+
end
|
51
57
|
end
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
|
59
|
+
context "#not_eq" do
|
60
|
+
it "accepts scalar value" do
|
61
|
+
expect(@vector.not_eq(51)).to eq(
|
62
|
+
@klass.new([true, false, true, true, true, true]))
|
63
|
+
end
|
64
|
+
|
65
|
+
it "accepts vector and compares corrensponding elements" do
|
66
|
+
expect(@vector.not_eq(@comparator)).to eq(
|
67
|
+
@klass.new([true, true, false, true, false, true]))
|
68
|
+
end
|
58
69
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@
|
70
|
+
|
71
|
+
context "#lt" do
|
72
|
+
it "accepts scalar value" do
|
73
|
+
expect(@vector.lt(51)).to eq(
|
74
|
+
@klass.new([true, false, false, false, true, true]))
|
75
|
+
end
|
76
|
+
|
77
|
+
it "accepts vector and compares corrensponding elements" do
|
78
|
+
expect(@vector.lt(@comparator)).to eq(
|
79
|
+
@klass.new([true,false,false,false,false,false]))
|
80
|
+
end
|
63
81
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
82
|
+
|
83
|
+
context "#lteq" do
|
84
|
+
it "accepts scalar value" do
|
85
|
+
expect(@vector.lteq(51)).to eq(
|
86
|
+
@klass.new([true, true, false, false, true, true]))
|
87
|
+
end
|
88
|
+
|
89
|
+
it "accepts vector and compares corrensponding elements" do
|
90
|
+
expect(@vector.lteq(@comparator)).to eq(
|
91
|
+
@klass.new([true,false,true,false,true,false]))
|
92
|
+
end
|
70
93
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
@
|
94
|
+
|
95
|
+
context "#mt" do
|
96
|
+
it "accepts scalar value" do
|
97
|
+
expect(@vector.mt(51)).to eq(
|
98
|
+
@klass.new([false, false, true, true, false, false]))
|
99
|
+
end
|
100
|
+
|
101
|
+
it "accepts vector and compares corrensponding elements" do
|
102
|
+
expect(@vector.mt(@comparator)).to eq(
|
103
|
+
@klass.new([false,true,false,true,false,true]))
|
104
|
+
end
|
75
105
|
end
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
106
|
+
|
107
|
+
context "#mteq" do
|
108
|
+
it "accepts scalar value" do
|
109
|
+
expect(@vector.mteq(51)).to eq(
|
110
|
+
@klass.new([false, true, true, true, false, false]))
|
111
|
+
end
|
112
|
+
|
113
|
+
it "accepts vector and compares corrensponding elements" do
|
114
|
+
expect(@vector.mteq(@comparator)).to eq(
|
115
|
+
@klass.new([false,true,true,true,true,true]))
|
116
|
+
end
|
82
117
|
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@
|
118
|
+
|
119
|
+
context "#in" do
|
120
|
+
it "checks if any of elements in the arg are present in the vector" do
|
121
|
+
expect(@vector.in([23,55,1,33,32])).to eq(
|
122
|
+
@klass.new([true, false, false, false, true, false]))
|
123
|
+
end
|
87
124
|
end
|
88
125
|
end
|
126
|
+
|
127
|
+
describe "categorical type" do
|
128
|
+
let(:dv) { Daru::Vector.new ['e', 'd', 'd', 'x', 'x'],
|
129
|
+
categories: ['a', 'x', 'c', 'd', 'e'], type: :category }
|
130
|
+
let(:comp) { Daru::Vector.new ['a', 'd', 'x', 'e', 'x'],
|
131
|
+
categories: ['a', 'x', 'c', 'd', 'e'], type: :category }
|
132
|
+
let(:query_bool_class) { Daru::Core::Query::BoolArray }
|
89
133
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
134
|
+
context "#eq" do
|
135
|
+
context "scalar" do
|
136
|
+
subject { dv.eq 'd' }
|
137
|
+
|
138
|
+
it { is_expected.to be_a query_bool_class }
|
139
|
+
its(:to_a) { is_expected.to eq [false, true, true, false, false] }
|
140
|
+
end
|
95
141
|
|
96
|
-
|
97
|
-
|
98
|
-
|
142
|
+
context "vector" do
|
143
|
+
subject { dv.eq comp }
|
144
|
+
|
145
|
+
it { is_expected.to be_a query_bool_class }
|
146
|
+
its(:to_a) { is_expected.to eq [false, true, false, false, true] }
|
147
|
+
end
|
99
148
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
149
|
+
|
150
|
+
context "#not_eq" do
|
151
|
+
context "scalar" do
|
152
|
+
subject { dv.not_eq 'd' }
|
153
|
+
|
154
|
+
it { is_expected.to be_a query_bool_class }
|
155
|
+
its(:to_a) { is_expected.to eq [true, false, false, true, true] }
|
156
|
+
end
|
157
|
+
|
158
|
+
context "vector" do
|
159
|
+
subject { dv.not_eq comp }
|
160
|
+
|
161
|
+
it { is_expected.to be_a query_bool_class }
|
162
|
+
its(:to_a) { is_expected.to eq [true, false, true, true, false] }
|
163
|
+
end
|
106
164
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
165
|
+
|
166
|
+
context "#lt" do
|
167
|
+
context "scalar" do
|
168
|
+
subject { dv.lt 'd' }
|
169
|
+
|
170
|
+
it { is_expected.to be_a query_bool_class }
|
171
|
+
its(:to_a) { is_expected.to eq [false, false, false, true, true] }
|
172
|
+
end
|
173
|
+
|
174
|
+
context "vector" do
|
175
|
+
subject { dv.lt comp }
|
176
|
+
|
177
|
+
it { is_expected.to be_a query_bool_class }
|
178
|
+
its(:to_a) { is_expected.to eq [false, false, false, true, false] }
|
179
|
+
end
|
111
180
|
end
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
181
|
+
|
182
|
+
context "#lteq" do
|
183
|
+
context "scalar" do
|
184
|
+
subject { dv.lteq 'd' }
|
185
|
+
|
186
|
+
it { is_expected.to be_a query_bool_class }
|
187
|
+
its(:to_a) { is_expected.to eq [false, true, true, true, true] }
|
188
|
+
end
|
189
|
+
|
190
|
+
context "vector" do
|
191
|
+
subject { dv.lteq comp }
|
192
|
+
|
193
|
+
it { is_expected.to be_a query_bool_class }
|
194
|
+
its(:to_a) { is_expected.to eq [false, true, false, true, true] }
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
context "#mt" do
|
199
|
+
context "scalar" do
|
200
|
+
subject { dv.mt 'd' }
|
201
|
+
|
202
|
+
it { is_expected.to be_a query_bool_class }
|
203
|
+
its(:to_a) { is_expected.to eq [true, false, false, false, false] }
|
204
|
+
end
|
205
|
+
|
206
|
+
context "vector" do
|
207
|
+
subject { dv.mt comp }
|
208
|
+
|
209
|
+
it { is_expected.to be_a query_bool_class }
|
210
|
+
its(:to_a) { is_expected.to eq [true, false, true, false, false] }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "#mteq" do
|
215
|
+
context "scalar" do
|
216
|
+
subject { dv.mteq 'd' }
|
217
|
+
|
218
|
+
it { is_expected.to be_a query_bool_class }
|
219
|
+
its(:to_a) { is_expected.to eq [true, true, true, false, false] }
|
220
|
+
end
|
221
|
+
|
222
|
+
context "vector" do
|
223
|
+
subject { dv.mteq comp }
|
224
|
+
|
225
|
+
it { is_expected.to be_a query_bool_class }
|
226
|
+
its(:to_a) { is_expected.to eq [true, true, true, false, true] }
|
227
|
+
end
|
118
228
|
end
|
229
|
+
|
230
|
+
# context "#in" do
|
231
|
+
# subject { dv.in ['b', 'd'] }
|
232
|
+
# it { is_expected.to be_a query_bool_class }
|
233
|
+
# its(:to_a) { is_expected.to eq [false, true, true, true, true] }
|
234
|
+
# end
|
119
235
|
end
|
120
236
|
end
|
121
237
|
end
|
@@ -153,18 +269,58 @@ describe "Arel-like syntax" do
|
|
153
269
|
end
|
154
270
|
|
155
271
|
context Daru::Vector do
|
156
|
-
|
157
|
-
|
272
|
+
context "non-categorical type" do
|
273
|
+
before do
|
274
|
+
@vector = Daru::Vector.new([2,5,1,22,51,4])
|
275
|
+
end
|
276
|
+
|
277
|
+
it "accepts a simple single statement" do
|
278
|
+
expect(@vector.where(@vector.lt(10))).to eq(
|
279
|
+
Daru::Vector.new([2,5,1,4], index: Daru::Index.new([0,1,2,5])))
|
280
|
+
end
|
281
|
+
|
282
|
+
it "accepts somewhat complex operator chaining" do
|
283
|
+
expect(@vector.where((@vector.lt(6) | @vector.eq(51)))).to eq(
|
284
|
+
Daru::Vector.new([2,5,1,51,4], index: Daru::Index.new([0,1,2,4,5])))
|
285
|
+
end
|
158
286
|
end
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
287
|
+
|
288
|
+
context "categorical type" do
|
289
|
+
let(:dv) { Daru::Vector.new ['a', 'c', 'x', 'x', 'c'],
|
290
|
+
categories: ['a', 'x', 'c'], type: :category }
|
291
|
+
|
292
|
+
context "simple single statement" do
|
293
|
+
subject { dv.where(dv.lt('x')) }
|
294
|
+
|
295
|
+
it { is_expected.to be_a Daru::Vector }
|
296
|
+
its(:type) { is_expected.to eq :category }
|
297
|
+
its(:to_a) { is_expected.to eq ['a'] }
|
298
|
+
its(:'index.to_a') { is_expected.to eq [0] }
|
299
|
+
end
|
300
|
+
|
301
|
+
context "complex operator chaining" do
|
302
|
+
subject { dv.where((dv.lt('x') | dv.eq('c'))) }
|
303
|
+
|
304
|
+
it { is_expected.to be_a Daru::Vector }
|
305
|
+
its(:type) { is_expected.to eq :category }
|
306
|
+
its(:to_a) { is_expected.to eq ['a', 'c', 'c'] }
|
307
|
+
its(:'index.to_a') { is_expected.to eq [0, 1, 4] }
|
308
|
+
end
|
309
|
+
|
310
|
+
context "preserve categories" do
|
311
|
+
subject { dv.where((dv.lt('x') | dv.eq('c'))) }
|
312
|
+
|
313
|
+
it { is_expected.to be_a Daru::Vector }
|
314
|
+
its(:type) { is_expected.to eq :category }
|
315
|
+
its(:to_a) { is_expected.to eq ['a', 'c', 'c'] }
|
316
|
+
its(:'index.to_a') { is_expected.to eq [0, 1, 4] }
|
317
|
+
its(:categories) { is_expected.to eq ['a', 'x', 'c'] }
|
318
|
+
end
|
163
319
|
end
|
164
320
|
|
165
|
-
it "
|
166
|
-
|
167
|
-
|
321
|
+
it "preserves name" do
|
322
|
+
named_vector = Daru::Vector.new([1,2,3], name: 'named')
|
323
|
+
expect(named_vector.where(named_vector.lteq(2)).name).to eq('named')
|
168
324
|
end
|
169
325
|
end
|
170
326
|
end
|