daru_lite 0.1.1 → 0.1.2
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/.rubocop_todo.yml +35 -33
- data/lib/daru_lite/data_frame/aggregatable.rb +165 -0
- data/lib/daru_lite/data_frame/calculatable.rb +140 -0
- data/lib/daru_lite/data_frame/convertible.rb +107 -0
- data/lib/daru_lite/data_frame/duplicatable.rb +64 -0
- data/lib/daru_lite/data_frame/fetchable.rb +301 -0
- data/lib/daru_lite/data_frame/filterable.rb +144 -0
- data/lib/daru_lite/data_frame/i_o_able.rb +179 -0
- data/lib/daru_lite/data_frame/indexable.rb +168 -0
- data/lib/daru_lite/data_frame/iterable.rb +339 -0
- data/lib/daru_lite/data_frame/joinable.rb +152 -0
- data/lib/daru_lite/data_frame/missable.rb +75 -0
- data/lib/daru_lite/data_frame/pivotable.rb +108 -0
- data/lib/daru_lite/data_frame/queryable.rb +67 -0
- data/lib/daru_lite/data_frame/setable.rb +109 -0
- data/lib/daru_lite/data_frame/sortable.rb +241 -0
- data/lib/daru_lite/dataframe.rb +138 -2353
- data/lib/daru_lite/index/index.rb +13 -0
- data/lib/daru_lite/maths/statistics/vector.rb +1 -1
- data/lib/daru_lite/vector/aggregatable.rb +9 -0
- data/lib/daru_lite/vector/calculatable.rb +78 -0
- data/lib/daru_lite/vector/convertible.rb +77 -0
- data/lib/daru_lite/vector/duplicatable.rb +17 -0
- data/lib/daru_lite/vector/fetchable.rb +175 -0
- data/lib/daru_lite/vector/filterable.rb +128 -0
- data/lib/daru_lite/vector/indexable.rb +77 -0
- data/lib/daru_lite/vector/iterable.rb +95 -0
- data/lib/daru_lite/vector/joinable.rb +17 -0
- data/lib/daru_lite/vector/missable.rb +124 -0
- data/lib/daru_lite/vector/queryable.rb +45 -0
- data/lib/daru_lite/vector/setable.rb +47 -0
- data/lib/daru_lite/vector/sortable.rb +113 -0
- data/lib/daru_lite/vector.rb +36 -932
- data/lib/daru_lite/version.rb +1 -1
- data/spec/data_frame/aggregatable_example.rb +65 -0
- data/spec/data_frame/buildable_example.rb +109 -0
- data/spec/data_frame/calculatable_example.rb +135 -0
- data/spec/data_frame/convertible_example.rb +180 -0
- data/spec/data_frame/duplicatable_example.rb +111 -0
- data/spec/data_frame/fetchable_example.rb +476 -0
- data/spec/data_frame/filterable_example.rb +250 -0
- data/spec/data_frame/indexable_example.rb +221 -0
- data/spec/data_frame/iterable_example.rb +465 -0
- data/spec/data_frame/joinable_example.rb +106 -0
- data/spec/data_frame/missable_example.rb +47 -0
- data/spec/data_frame/pivotable_example.rb +297 -0
- data/spec/data_frame/queryable_example.rb +92 -0
- data/spec/data_frame/setable_example.rb +482 -0
- data/spec/data_frame/sortable_example.rb +350 -0
- data/spec/dataframe_spec.rb +181 -3289
- data/spec/index/index_spec.rb +8 -0
- data/spec/vector/aggregatable_example.rb +27 -0
- data/spec/vector/calculatable_example.rb +82 -0
- data/spec/vector/convertible_example.rb +126 -0
- data/spec/vector/duplicatable_example.rb +48 -0
- data/spec/vector/fetchable_example.rb +463 -0
- data/spec/vector/filterable_example.rb +165 -0
- data/spec/vector/indexable_example.rb +201 -0
- data/spec/vector/iterable_example.rb +111 -0
- data/spec/vector/joinable_example.rb +25 -0
- data/spec/vector/missable_example.rb +88 -0
- data/spec/vector/queryable_example.rb +91 -0
- data/spec/vector/setable_example.rb +300 -0
- data/spec/vector/sortable_example.rb +242 -0
- data/spec/vector_spec.rb +111 -1805
- metadata +86 -2
@@ -0,0 +1,300 @@
|
|
1
|
+
shared_examples_for 'a setable Vector' do |dtype|
|
2
|
+
describe "#[]=" do
|
3
|
+
context DaruLite::Index do
|
4
|
+
let(:vector) do
|
5
|
+
DaruLite::Vector.new(
|
6
|
+
[1,2,3,4,5],
|
7
|
+
name: :yoga,
|
8
|
+
index: [:yoda, :anakin, :obi, :padme, :r2d2],
|
9
|
+
dtype:
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "assigns at the specified index" do
|
14
|
+
vector[:yoda] = 666
|
15
|
+
expect(vector[:yoda]).to eq(666)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "assigns at the specified Integer index" do
|
19
|
+
vector[0] = 666
|
20
|
+
expect(vector[:yoda]).to eq(666)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "sets dtype to Array if a nil is assigned" do
|
24
|
+
vector[0] = nil
|
25
|
+
expect(vector.dtype).to eq(:array)
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'mixed index Vector' do
|
29
|
+
let(:vector) do
|
30
|
+
DaruLite::Vector.new([1, 2, 3, 4], index: ['a', :a, 0, 66])
|
31
|
+
end
|
32
|
+
|
33
|
+
it "assigns correctly" do
|
34
|
+
vector['a'] = 666
|
35
|
+
expect(vector['a']).to eq(666)
|
36
|
+
|
37
|
+
vector[0] = 666
|
38
|
+
expect(vector[0]).to eq(666)
|
39
|
+
|
40
|
+
vector[3] = 666
|
41
|
+
expect(vector[3]).to eq(666)
|
42
|
+
|
43
|
+
expect(vector).to eq(
|
44
|
+
DaruLite::Vector.new(
|
45
|
+
[666, 2, 666, 666],
|
46
|
+
index: ['a', :a, 0, 66])
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context DaruLite::MultiIndex do
|
53
|
+
let(:tuples) do
|
54
|
+
[
|
55
|
+
[:a,:one,:bar],
|
56
|
+
[:a,:one,:baz],
|
57
|
+
[:a,:two,:bar],
|
58
|
+
[:a,:two,:baz],
|
59
|
+
[:b,:one,:bar],
|
60
|
+
[:b,:two,:bar],
|
61
|
+
[:b,:two,:baz],
|
62
|
+
[:b,:one,:foo],
|
63
|
+
[:c,:one,:bar],
|
64
|
+
[:c,:one,:baz],
|
65
|
+
[:c,:two,:foo],
|
66
|
+
[:c,:two,:bar]
|
67
|
+
]
|
68
|
+
end
|
69
|
+
let(:multi_index) { DaruLite::MultiIndex.from_tuples(tuples) }
|
70
|
+
let(:vector) do
|
71
|
+
DaruLite::Vector.new(
|
72
|
+
Array.new(12) { |i| i },
|
73
|
+
index: multi_index,
|
74
|
+
dtype:,
|
75
|
+
name: :mi_vector
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "assigns all lower layer indices when specified a first layer index" do
|
80
|
+
vector[:b] = 69
|
81
|
+
expect(vector).to eq(
|
82
|
+
DaruLite::Vector.new([0, 1, 2, 3, 69, 69, 69, 69, 8, 9, 10, 11],
|
83
|
+
index: multi_index,
|
84
|
+
name: :top_layer_assignment,
|
85
|
+
dtype:
|
86
|
+
)
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "assigns all lower indices when specified first and second layer index" do
|
91
|
+
vector[:b, :one] = 69
|
92
|
+
expect(vector).to eq(
|
93
|
+
DaruLite::Vector.new([0, 1, 2, 3, 69, 5, 6, 69, 8, 9, 10, 11],
|
94
|
+
index: multi_index,
|
95
|
+
name: :second_layer_assignment,
|
96
|
+
dtype:
|
97
|
+
)
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
it "assigns just the precise value when specified complete tuple" do
|
102
|
+
vector[:b, :one, :foo] = 69
|
103
|
+
expect(vector).to eq(
|
104
|
+
DaruLite::Vector.new([0, 1, 2, 3, 4, 5, 6, 69, 8, 9, 10, 11],
|
105
|
+
index: multi_index,
|
106
|
+
name: :precise_assignment,
|
107
|
+
dtype:
|
108
|
+
)
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "assigns correctly when numeric index" do
|
113
|
+
vector[7] = 69
|
114
|
+
expect(vector).to eq(
|
115
|
+
DaruLite::Vector.new([0, 1, 2, 3, 4, 5, 6, 69, 8, 9, 10, 11],
|
116
|
+
index: multi_index,
|
117
|
+
name: :precise_assignment,
|
118
|
+
dtype:
|
119
|
+
)
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "fails predictably on unknown index" do
|
124
|
+
expect { vector[:d] = 69 }.to raise_error(IndexError)
|
125
|
+
expect { vector[:b, :three] = 69 }.to raise_error(IndexError)
|
126
|
+
expect { vector[:b, :two, :test] = 69 }.to raise_error(IndexError)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context DaruLite::CategoricalIndex do
|
131
|
+
subject { vector }
|
132
|
+
|
133
|
+
context "non-numerical index" do
|
134
|
+
let (:idx) { DaruLite::CategoricalIndex.new [:a, :b, :a, :a, :c] }
|
135
|
+
let (:vector) { DaruLite::Vector.new 'a'..'e', index: idx }
|
136
|
+
|
137
|
+
context "single category" do
|
138
|
+
context "multiple instances" do
|
139
|
+
before { vector[:a] = 'x' }
|
140
|
+
|
141
|
+
its(:size) { is_expected.to eq 5 }
|
142
|
+
its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'e'] }
|
143
|
+
its(:index) { is_expected.to eq idx }
|
144
|
+
end
|
145
|
+
|
146
|
+
context "single instance" do
|
147
|
+
before { vector[:b] = 'x' }
|
148
|
+
|
149
|
+
its(:size) { is_expected.to eq 5 }
|
150
|
+
its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
|
151
|
+
its(:index) { is_expected.to eq idx }
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "multiple categories" do
|
156
|
+
before { vector[:a, :c] = 'x' }
|
157
|
+
|
158
|
+
its(:size) { is_expected.to eq 5 }
|
159
|
+
its(:to_a) { is_expected.to eq ['x', 'b', 'x', 'x', 'x'] }
|
160
|
+
its(:index) { is_expected.to eq idx }
|
161
|
+
end
|
162
|
+
|
163
|
+
context "multiple positional indexes" do
|
164
|
+
before { vector[0, 1, 2] = 'x' }
|
165
|
+
|
166
|
+
its(:size) { is_expected.to eq 5 }
|
167
|
+
its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
|
168
|
+
its(:index) { is_expected.to eq idx }
|
169
|
+
end
|
170
|
+
|
171
|
+
context "single positional index" do
|
172
|
+
before { vector[1] = 'x' }
|
173
|
+
|
174
|
+
its(:size) { is_expected.to eq 5 }
|
175
|
+
its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
|
176
|
+
its(:index) { is_expected.to eq idx }
|
177
|
+
end
|
178
|
+
|
179
|
+
context "invalid category" do
|
180
|
+
it { expect { vector[:x] = 'x' }.to raise_error IndexError }
|
181
|
+
end
|
182
|
+
|
183
|
+
context "invalid positional index" do
|
184
|
+
it { expect { vector[30] = 'x'}.to raise_error IndexError }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "numerical index" do
|
189
|
+
let (:idx) { DaruLite::CategoricalIndex.new [1, 1, 2, 2, 3] }
|
190
|
+
let (:vector) { DaruLite::Vector.new 'a'..'e', index: idx }
|
191
|
+
|
192
|
+
context "single category" do
|
193
|
+
before { vector[1] = 'x' }
|
194
|
+
|
195
|
+
its(:size) { is_expected.to eq 5 }
|
196
|
+
its(:to_a) { is_expected.to eq ['x', 'x', 'c', 'd', 'e'] }
|
197
|
+
its(:index) { is_expected.to eq idx }
|
198
|
+
end
|
199
|
+
|
200
|
+
context "multiple categories" do
|
201
|
+
before { vector[1, 2] = 'x' }
|
202
|
+
|
203
|
+
its(:size) { is_expected.to eq 5 }
|
204
|
+
its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'x', 'e'] }
|
205
|
+
its(:index) { is_expected.to eq idx }
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
describe "#set_at" do
|
212
|
+
context DaruLite::Index do
|
213
|
+
let (:idx) { DaruLite::Index.new [1, 0, :c] }
|
214
|
+
let (:dv) { DaruLite::Vector.new ['a', 'b', 'c'], index: idx }
|
215
|
+
|
216
|
+
context "single position" do
|
217
|
+
subject { dv }
|
218
|
+
before { dv.set_at [1], 'x' }
|
219
|
+
|
220
|
+
its(:to_a) { is_expected.to eq ['a', 'x', 'c'] }
|
221
|
+
end
|
222
|
+
|
223
|
+
context "multiple positions" do
|
224
|
+
subject { dv }
|
225
|
+
before { dv.set_at [0, 2], 'x' }
|
226
|
+
|
227
|
+
its(:to_a) { is_expected.to eq ['x', 'b', 'x'] }
|
228
|
+
end
|
229
|
+
|
230
|
+
context "invalid position" do
|
231
|
+
it { expect { dv.set_at [3], 'x' }.to raise_error IndexError }
|
232
|
+
end
|
233
|
+
|
234
|
+
context "invalid positions" do
|
235
|
+
it { expect { dv.set_at [2, 3], 'x' }.to raise_error IndexError }
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context DaruLite::MultiIndex do
|
240
|
+
let(:idx) do
|
241
|
+
DaruLite::MultiIndex.from_tuples [
|
242
|
+
[:a,:one,:bar],
|
243
|
+
[:a,:one,:baz],
|
244
|
+
[:b,:two,:bar],
|
245
|
+
[:a,:two,:baz],
|
246
|
+
]
|
247
|
+
end
|
248
|
+
let(:dv) { DaruLite::Vector.new 1..4, index: idx }
|
249
|
+
|
250
|
+
context "single position" do
|
251
|
+
subject { dv }
|
252
|
+
before { dv.set_at [1], 'x' }
|
253
|
+
|
254
|
+
its(:to_a) { is_expected.to eq [1, 'x', 3, 4] }
|
255
|
+
end
|
256
|
+
|
257
|
+
context "multiple positions" do
|
258
|
+
subject { dv }
|
259
|
+
before { dv.set_at [2, 3], 'x' }
|
260
|
+
|
261
|
+
its(:to_a) { is_expected.to eq [1, 2, 'x', 'x'] }
|
262
|
+
end
|
263
|
+
|
264
|
+
context "invalid position" do
|
265
|
+
it { expect { dv.set_at [4], 'x' }.to raise_error IndexError }
|
266
|
+
end
|
267
|
+
|
268
|
+
context "invalid positions" do
|
269
|
+
it { expect { dv.set_at [2, 4], 'x' }.to raise_error IndexError }
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context DaruLite::CategoricalIndex do
|
274
|
+
let (:idx) { DaruLite::CategoricalIndex.new [:a, 1, 1, :a, :c] }
|
275
|
+
let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
|
276
|
+
|
277
|
+
context "multiple positional indexes" do
|
278
|
+
subject { dv }
|
279
|
+
before { dv.set_at [0, 1, 2], 'x' }
|
280
|
+
|
281
|
+
its(:to_a) { is_expected.to eq ['x', 'x', 'x', 'd', 'e'] }
|
282
|
+
end
|
283
|
+
|
284
|
+
context "single positional index" do
|
285
|
+
subject { dv }
|
286
|
+
before { dv.set_at [1], 'x' }
|
287
|
+
|
288
|
+
its(:to_a) { is_expected.to eq ['a', 'x', 'c', 'd', 'e'] }
|
289
|
+
end
|
290
|
+
|
291
|
+
context "invalid position" do
|
292
|
+
it { expect { dv.set_at [5], 'x' }.to raise_error IndexError }
|
293
|
+
end
|
294
|
+
|
295
|
+
context "invalid positions" do
|
296
|
+
it { expect { dv.set_at [2, 5], 'x' }.to raise_error IndexError }
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
shared_examples_for 'a sortable Vector' do |dtype|
|
2
|
+
describe "#reorder!" do
|
3
|
+
subject { vector_with_dtype.reorder!([3, 2, 1, 0]) }
|
4
|
+
|
5
|
+
let(:vector_with_dtype) do
|
6
|
+
DaruLite::Vector.new(
|
7
|
+
[1, 2, 3, 4],
|
8
|
+
index: [:a, :b, :c, :d],
|
9
|
+
dtype:
|
10
|
+
)
|
11
|
+
end
|
12
|
+
let(:arranged_vector) do
|
13
|
+
DaruLite::Vector.new([4,3,2,1], index: [:d, :c, :b, :a], dtype:)
|
14
|
+
end
|
15
|
+
|
16
|
+
before { subject }
|
17
|
+
|
18
|
+
it "rearranges with passed order" do
|
19
|
+
expect(vector_with_dtype).to eq arranged_vector
|
20
|
+
end
|
21
|
+
|
22
|
+
it "doesn't change dtype" do
|
23
|
+
expect(vector_with_dtype.data.class).to eq arranged_vector.data.class
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
context "#sort" do
|
29
|
+
context DaruLite::Index do
|
30
|
+
let(:vector) do
|
31
|
+
DaruLite::Vector.new([33, 2, 15, 332, 1], name: :dv, index: [:a, :b, :c, :d, :e])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "sorts the vector with defaults and returns a new vector, preserving indexing" do
|
35
|
+
expect(vector.sort).to eq(
|
36
|
+
DaruLite::Vector.new([1,2,15,33,332], name: :dv, index: [:e, :b, :c, :a, :d])
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "sorts the vector in descending order" do
|
41
|
+
expect(vector.sort(ascending: false)).to eq(
|
42
|
+
DaruLite::Vector.new([332,33,15,2,1], name: :dv, index: [:d, :a, :c, :b, :e])
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when a block is passed' do
|
47
|
+
subject { vector.sort { |a,b| a.length <=> b.length } }
|
48
|
+
|
49
|
+
let(:vector) { DaruLite::Vector.new ["My Jazz Guitar", "Jazz", "My", "Guitar"] }
|
50
|
+
|
51
|
+
it "sorts vector accordingly" do
|
52
|
+
expect(subject).to eq(
|
53
|
+
DaruLite::Vector.new(["My", "Jazz", "Guitar", "My Jazz Guitar"], index: [2, 1, 3, 0])
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when vector contains nils and numeric data' do
|
59
|
+
let(:vector) { DaruLite::Vector.new([22, 4, nil, 111, nil, 2]) }
|
60
|
+
|
61
|
+
it "places nils near the beginning of the vector when sorting ascendingly" do
|
62
|
+
expect(vector.sort).to eq(
|
63
|
+
DaruLite::Vector.new([nil, nil, 2, 4, 22, 111], index: [2, 4, 5, 1, 0, 3])
|
64
|
+
)
|
65
|
+
end if dtype == :array
|
66
|
+
|
67
|
+
it "places nils near the beginning of the vector when sorting descendingly" do
|
68
|
+
expect(vector.sort(ascending: false)).to eq(
|
69
|
+
DaruLite::Vector.new [111, 22, 4, 2, nil, nil], index: [3, 0, 1, 5, 4, 2]
|
70
|
+
)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when vector contains nils and non-numeric data' do
|
75
|
+
let(:vector) { DaruLite::Vector.new(['a','b', nil, 'aa', '1234', nil]) }
|
76
|
+
|
77
|
+
it "correctly sorts vector in ascending order" do
|
78
|
+
expect(vector.sort(ascending: true)).to eq(
|
79
|
+
DaruLite::Vector.new([nil, nil, '1234', 'a', 'aa', 'b'], index: [2, 5, 4, 0, 3, 1])
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "correctly sorts vector in descending order" do
|
84
|
+
expect(vector.sort(ascending: false)).to eq(
|
85
|
+
DaruLite::Vector.new(['b', 'aa', 'a', '1234', nil, nil], index: [1, 3, 0, 4, 5, 2])
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context DaruLite::MultiIndex do
|
92
|
+
let(:multi_index) do
|
93
|
+
DaruLite::MultiIndex.from_tuples([
|
94
|
+
[:a, :one, :foo],
|
95
|
+
[:a, :two, :bar],
|
96
|
+
[:b, :one, :bar],
|
97
|
+
[:b, :two, :baz],
|
98
|
+
[:b, :three, :bar]
|
99
|
+
])
|
100
|
+
end
|
101
|
+
let(:vector) do
|
102
|
+
DaruLite::Vector.new(
|
103
|
+
[44, 22, 111, 0, -56],
|
104
|
+
index: multi_index,
|
105
|
+
name: :unsorted,
|
106
|
+
dtype:
|
107
|
+
)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "sorts vector" do
|
111
|
+
mi_asc = DaruLite::MultiIndex.from_tuples([
|
112
|
+
[:b, :three, :bar],
|
113
|
+
[:b, :two, :baz],
|
114
|
+
[:a, :two, :bar],
|
115
|
+
[:a, :one, :foo],
|
116
|
+
[:b, :one, :bar]
|
117
|
+
])
|
118
|
+
expect(vector.sort).to eq(
|
119
|
+
DaruLite::Vector.new([-56,0,22,44,111], index: mi_asc, name: :ascending, dtype:)
|
120
|
+
)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "sorts in descending" do
|
124
|
+
mi_dsc = DaruLite::MultiIndex.from_tuples([
|
125
|
+
[:b, :one, :bar],
|
126
|
+
[:a, :one, :foo],
|
127
|
+
[:a, :two, :bar],
|
128
|
+
[:b, :two, :baz],
|
129
|
+
[:b, :three, :bar]
|
130
|
+
])
|
131
|
+
expect(vector.sort(ascending: false)).to eq(
|
132
|
+
DaruLite::Vector.new([111, 44, 22, 0, -56], index: mi_dsc, name: :descending, dtype:)
|
133
|
+
)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "sorts using the supplied block" do
|
137
|
+
mi_abs = DaruLite::MultiIndex.from_tuples([
|
138
|
+
[:b, :two, :baz],
|
139
|
+
[:a, :two, :bar],
|
140
|
+
[:a, :one, :foo],
|
141
|
+
[:b, :three, :bar],
|
142
|
+
[:b, :one, :bar]
|
143
|
+
])
|
144
|
+
expect(vector.sort { |a,b| a.abs <=> b.abs }).to eq(
|
145
|
+
DaruLite::Vector.new([0, 22, 44, -56, 111], index: mi_abs, name: :sort_abs, dtype:)
|
146
|
+
)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context DaruLite::CategoricalIndex do
|
151
|
+
let(:idx) { DaruLite::CategoricalIndex.new [:a, 1, :a, 1, :c] }
|
152
|
+
let(:dv_numeric) { DaruLite::Vector.new [4, 5, 3, 2, 1], index: idx }
|
153
|
+
let(:dv_string) { DaruLite::Vector.new ['xxxx', 'zzzzz', 'ccc', 'bb', 'a'], index: idx }
|
154
|
+
let(:dv_nil) { DaruLite::Vector.new [3, nil, 2, 1, -1], index: idx }
|
155
|
+
|
156
|
+
context "increasing order" do
|
157
|
+
context "numeric" do
|
158
|
+
subject { dv_numeric.sort }
|
159
|
+
|
160
|
+
its(:size) { is_expected.to eq 5 }
|
161
|
+
its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
|
162
|
+
its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
|
163
|
+
end
|
164
|
+
|
165
|
+
context "non-numeric" do
|
166
|
+
subject { dv_string.sort }
|
167
|
+
|
168
|
+
its(:size) { is_expected.to eq 5 }
|
169
|
+
its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
|
170
|
+
its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
|
171
|
+
end
|
172
|
+
|
173
|
+
context "block" do
|
174
|
+
subject { dv_string.sort { |a, b| a.length <=> b.length } }
|
175
|
+
|
176
|
+
its(:to_a) { is_expected.to eq ['a', 'bb', 'ccc', 'xxxx', 'zzzzz'] }
|
177
|
+
its(:'index.to_a') { is_expected.to eq [:c, 1, :a, :a, 1] }
|
178
|
+
end
|
179
|
+
|
180
|
+
context "nils" do
|
181
|
+
subject { dv_nil.sort }
|
182
|
+
|
183
|
+
its(:to_a) { is_expected.to eq [nil, -1, 1, 2, 3] }
|
184
|
+
its(:'index.to_a') { is_expected.to eq [1, :c, 1, :a, :a] }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "decreasing order" do
|
189
|
+
context "numeric" do
|
190
|
+
subject { dv_numeric.sort(ascending: false) }
|
191
|
+
|
192
|
+
its(:size) { is_expected.to eq 5 }
|
193
|
+
its(:to_a) { is_expected.to eq [5, 4, 3, 2, 1] }
|
194
|
+
its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
|
195
|
+
end
|
196
|
+
|
197
|
+
context "non-numeric" do
|
198
|
+
subject { dv_string.sort(ascending: false) }
|
199
|
+
|
200
|
+
its(:size) { is_expected.to eq 5 }
|
201
|
+
its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
|
202
|
+
its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
|
203
|
+
end
|
204
|
+
|
205
|
+
context "block" do
|
206
|
+
subject do
|
207
|
+
dv_string.sort(ascending: false) { |a, b| a.length <=> b.length }
|
208
|
+
end
|
209
|
+
|
210
|
+
its(:to_a) { is_expected.to eq ['zzzzz', 'xxxx', 'ccc', 'bb', 'a'] }
|
211
|
+
its(:'index.to_a') { is_expected.to eq [1, :a, :a, 1, :c] }
|
212
|
+
end
|
213
|
+
|
214
|
+
context "nils" do
|
215
|
+
subject { dv_nil.sort(ascending: false) }
|
216
|
+
|
217
|
+
its(:to_a) { is_expected.to eq [3, 2, 1, -1, nil] }
|
218
|
+
its(:'index.to_a') { is_expected.to eq [:a, :a, 1, :c, 1] }
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "#sort_by_index" do
|
225
|
+
let(:asc) { vector.sort_by_index }
|
226
|
+
let(:desc) { vector.sort_by_index(ascending: false) }
|
227
|
+
|
228
|
+
context 'numeric vector' do
|
229
|
+
let(:vector) { DaruLite::Vector.new [11, 13, 12], index: [23, 21, 22] }
|
230
|
+
|
231
|
+
specify { expect(asc.to_a).to eq [13, 12, 11] }
|
232
|
+
specify { expect(desc.to_a).to eq [11, 12, 13] }
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'mix variable type index' do
|
236
|
+
let(:vector) { DaruLite::Vector.new [11, Float::NAN, nil], index: [21, 23, 22] }
|
237
|
+
|
238
|
+
specify { expect(asc.to_a).to eq [11, nil, Float::NAN] }
|
239
|
+
specify { expect(desc.to_a).to eq [Float::NAN, nil, 11] }
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|