daru_lite 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +35 -33
  3. data/lib/daru_lite/data_frame/aggregatable.rb +165 -0
  4. data/lib/daru_lite/data_frame/calculatable.rb +140 -0
  5. data/lib/daru_lite/data_frame/convertible.rb +107 -0
  6. data/lib/daru_lite/data_frame/duplicatable.rb +64 -0
  7. data/lib/daru_lite/data_frame/fetchable.rb +301 -0
  8. data/lib/daru_lite/data_frame/filterable.rb +144 -0
  9. data/lib/daru_lite/data_frame/i_o_able.rb +179 -0
  10. data/lib/daru_lite/data_frame/indexable.rb +168 -0
  11. data/lib/daru_lite/data_frame/iterable.rb +339 -0
  12. data/lib/daru_lite/data_frame/joinable.rb +152 -0
  13. data/lib/daru_lite/data_frame/missable.rb +75 -0
  14. data/lib/daru_lite/data_frame/pivotable.rb +108 -0
  15. data/lib/daru_lite/data_frame/queryable.rb +67 -0
  16. data/lib/daru_lite/data_frame/setable.rb +109 -0
  17. data/lib/daru_lite/data_frame/sortable.rb +241 -0
  18. data/lib/daru_lite/dataframe.rb +138 -2353
  19. data/lib/daru_lite/index/index.rb +14 -1
  20. data/lib/daru_lite/index/multi_index.rb +9 -0
  21. data/lib/daru_lite/maths/statistics/vector.rb +1 -1
  22. data/lib/daru_lite/vector/aggregatable.rb +9 -0
  23. data/lib/daru_lite/vector/calculatable.rb +78 -0
  24. data/lib/daru_lite/vector/convertible.rb +77 -0
  25. data/lib/daru_lite/vector/duplicatable.rb +17 -0
  26. data/lib/daru_lite/vector/fetchable.rb +175 -0
  27. data/lib/daru_lite/vector/filterable.rb +128 -0
  28. data/lib/daru_lite/vector/indexable.rb +77 -0
  29. data/lib/daru_lite/vector/iterable.rb +95 -0
  30. data/lib/daru_lite/vector/joinable.rb +17 -0
  31. data/lib/daru_lite/vector/missable.rb +124 -0
  32. data/lib/daru_lite/vector/queryable.rb +45 -0
  33. data/lib/daru_lite/vector/setable.rb +47 -0
  34. data/lib/daru_lite/vector/sortable.rb +113 -0
  35. data/lib/daru_lite/vector.rb +36 -932
  36. data/lib/daru_lite/version.rb +1 -1
  37. data/spec/data_frame/aggregatable_example.rb +65 -0
  38. data/spec/data_frame/buildable_example.rb +109 -0
  39. data/spec/data_frame/calculatable_example.rb +135 -0
  40. data/spec/data_frame/convertible_example.rb +180 -0
  41. data/spec/data_frame/duplicatable_example.rb +111 -0
  42. data/spec/data_frame/fetchable_example.rb +476 -0
  43. data/spec/data_frame/filterable_example.rb +409 -0
  44. data/spec/data_frame/indexable_example.rb +221 -0
  45. data/spec/data_frame/iterable_example.rb +465 -0
  46. data/spec/data_frame/joinable_example.rb +106 -0
  47. data/spec/data_frame/missable_example.rb +47 -0
  48. data/spec/data_frame/pivotable_example.rb +297 -0
  49. data/spec/data_frame/queryable_example.rb +92 -0
  50. data/spec/data_frame/setable_example.rb +482 -0
  51. data/spec/data_frame/sortable_example.rb +350 -0
  52. data/spec/dataframe_spec.rb +181 -3289
  53. data/spec/index/categorical_index_spec.rb +27 -8
  54. data/spec/index/index_spec.rb +21 -0
  55. data/spec/index/multi_index_spec.rb +85 -76
  56. data/spec/vector/aggregatable_example.rb +27 -0
  57. data/spec/vector/calculatable_example.rb +82 -0
  58. data/spec/vector/convertible_example.rb +126 -0
  59. data/spec/vector/duplicatable_example.rb +48 -0
  60. data/spec/vector/fetchable_example.rb +463 -0
  61. data/spec/vector/filterable_example.rb +165 -0
  62. data/spec/vector/indexable_example.rb +201 -0
  63. data/spec/vector/iterable_example.rb +111 -0
  64. data/spec/vector/joinable_example.rb +25 -0
  65. data/spec/vector/missable_example.rb +88 -0
  66. data/spec/vector/queryable_example.rb +91 -0
  67. data/spec/vector/setable_example.rb +300 -0
  68. data/spec/vector/sortable_example.rb +242 -0
  69. data/spec/vector_spec.rb +111 -1805
  70. metadata +86 -2
@@ -0,0 +1,463 @@
1
+ shared_examples_for 'a fetchable 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 "returns an element after passing an index" do
14
+ expect(vector[:yoda]).to eq(1)
15
+ end
16
+
17
+ it "returns an element after passing a numeric index" do
18
+ expect(vector[0]).to eq(1)
19
+ end
20
+
21
+ it "returns a vector with given indices for multiple indices" do
22
+ expect(vector[:yoda, :anakin]).to eq(
23
+ DaruLite::Vector.new([1, 2], name: :yoda, index: [:yoda, :anakin], dtype:)
24
+ )
25
+ end
26
+
27
+ it "returns a vector with given indices for multiple numeric indices" do
28
+ expect(vector[0, 1]).to eq(
29
+ DaruLite::Vector.new([1, 2], name: :yoda, index: [:yoda, :anakin], dtype:)
30
+ )
31
+ end
32
+
33
+ it "returns a vector when specified symbol Range" do
34
+ expect(vector[:yoda..:anakin]).to eq(
35
+ DaruLite::Vector.new([1, 2], index: [:yoda, :anakin], name: :yoga, dtype:)
36
+ )
37
+ end
38
+
39
+ it "returns a vector when specified numeric Range" do
40
+ expect(vector[3..4]).to eq(
41
+ DaruLite::Vector.new([4,5], name: :yoga, index: [:padme, :r2d2], dtype:)
42
+ )
43
+ end
44
+
45
+ it "returns correct results for index of multiple index" do
46
+ v = DaruLite::Vector.new([1, 2, 3, 4], index: ['a', 'c', 1, :a])
47
+ expect(v['a']).to eq(1)
48
+ expect(v[:a]).to eq(4)
49
+ expect(v[1]).to eq(3)
50
+ expect(v[0]).to eq(1)
51
+ end
52
+
53
+ it "raises exception for invalid index" do
54
+ expect { vector[:foo] }.to raise_error(IndexError)
55
+ expect { vector[:obi, :foo] }.to raise_error(IndexError)
56
+ end
57
+ end
58
+
59
+ describe DaruLite::MultiIndex do
60
+ let(:tuples) do
61
+ [
62
+ [:a,:one,:bar],
63
+ [:a,:one,:baz],
64
+ [:a,:two,:bar],
65
+ [:a,:two,:baz],
66
+ [:b,:one,:bar],
67
+ [:b,:two,:bar],
68
+ [:b,:two,:baz],
69
+ [:b,:one,:foo],
70
+ [:c,:one,:bar],
71
+ [:c,:one,:baz],
72
+ [:c,:two,:foo],
73
+ [:c,:two,:bar],
74
+ [:d,:one,:foo]
75
+ ]
76
+ end
77
+ let(:multi_index) { DaruLite::MultiIndex.from_tuples(tuples) }
78
+ let(:vector) do
79
+ DaruLite::Vector.new(
80
+ Array.new(13) { |i| i },
81
+ index: multi_index,
82
+ dtype:,
83
+ name: :mi_vector
84
+ )
85
+ end
86
+
87
+ it "returns a single element when passed a row number" do
88
+ expect(vector[1]).to eq(1)
89
+ end
90
+
91
+ it "returns a single element when passed the full tuple" do
92
+ expect(vector[:a, :one, :baz]).to eq(1)
93
+ end
94
+
95
+ it "returns sub vector when passed first layer of tuple" do
96
+ index = DaruLite::MultiIndex.from_tuples([
97
+ [:one,:bar],
98
+ [:one,:baz],
99
+ [:two,:bar],
100
+ [:two,:baz]]
101
+ )
102
+ expect(vector[:a]).to eq(
103
+ DaruLite::Vector.new([0,1,2,3], index:, dtype:, name: :sub_vector)
104
+ )
105
+ end
106
+
107
+ it "returns sub vector when passed first and second layer of tuple" do
108
+ index = DaruLite::MultiIndex.from_tuples([[:foo], [:bar]])
109
+ expect(vector[:c,:two]).to eq(
110
+ DaruLite::Vector.new([10,11], index:, dtype:, name: :sub_sub_vector)
111
+ )
112
+ end
113
+
114
+ it "returns sub vector not a single element when passed the partial tuple" do
115
+ index = DaruLite::MultiIndex.from_tuples([[:foo]])
116
+ expect(vector[:d, :one]).to eq(
117
+ DaruLite::Vector.new([12], index:, dtype:, name: :sub_sub_vector)
118
+ )
119
+ end
120
+
121
+ it "returns a vector with corresponding MultiIndex when specified numeric Range" do
122
+ index = DaruLite::MultiIndex.from_tuples([
123
+ [:a,:two,:baz],
124
+ [:b,:one,:bar],
125
+ [:b,:two,:bar],
126
+ [:b,:two,:baz],
127
+ [:b,:one,:foo],
128
+ [:c,:one,:bar],
129
+ [:c,:one,:baz]
130
+ ])
131
+ expect(vector[3..9]).to eq(
132
+ DaruLite::Vector.new([3,4,5,6,7,8,9], index:, dtype:, name: :slice)
133
+ )
134
+ end
135
+
136
+ it "raises exception for invalid index" do
137
+ expect { vector[:foo] }.to raise_error(IndexError)
138
+ expect { vector[:a, :two, :foo] }.to raise_error(IndexError)
139
+ expect { vector[:x, :one] }.to raise_error(IndexError)
140
+ end
141
+ end
142
+
143
+ context DaruLite::CategoricalIndex do
144
+ # before { skip }
145
+ context "non-numerical index" do
146
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, :b, :a, :a, :c] }
147
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
148
+
149
+ context "single category" do
150
+ context "multiple instances" do
151
+ subject { dv[:a] }
152
+
153
+ it { is_expected.to be_a DaruLite::Vector }
154
+ its(:size) { is_expected.to eq 3 }
155
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd'] }
156
+ its(:index) { is_expected.to eq(
157
+ DaruLite::CategoricalIndex.new([:a, :a, :a])) }
158
+ end
159
+
160
+ context "single instance" do
161
+ subject { dv[:c] }
162
+
163
+ it { is_expected.to eq 'e' }
164
+ end
165
+ end
166
+
167
+ context "multiple categories" do
168
+ subject { dv[:a, :c] }
169
+
170
+ it { is_expected.to be_a DaruLite::Vector }
171
+ its(:size) { is_expected.to eq 4 }
172
+ its(:to_a) { is_expected.to eq ['a', 'c', 'd', 'e'] }
173
+ its(:index) { is_expected.to eq(
174
+ DaruLite::CategoricalIndex.new([:a, :a, :a, :c])) }
175
+ end
176
+
177
+ context "multiple positional indexes" do
178
+ subject { dv[0, 1, 2] }
179
+
180
+ it { is_expected.to be_a DaruLite::Vector }
181
+ its(:size) { is_expected.to eq 3 }
182
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
183
+ its(:index) { is_expected.to eq(
184
+ DaruLite::CategoricalIndex.new([:a, :b, :a])) }
185
+ end
186
+
187
+ context "single positional index" do
188
+ subject { dv[1] }
189
+
190
+ it { is_expected.to eq 'b' }
191
+ end
192
+
193
+ context "invalid category" do
194
+ it { expect { dv[:x] }.to raise_error IndexError }
195
+ end
196
+
197
+ context "invalid positional index" do
198
+ it { expect { dv[30] }.to raise_error IndexError }
199
+ end
200
+ end
201
+
202
+ context "numerical index" do
203
+ let (:idx) { DaruLite::CategoricalIndex.new [1, 1, 2, 2, 3] }
204
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
205
+
206
+ context "single category" do
207
+ context "multiple instances" do
208
+ subject { dv[1] }
209
+
210
+ it { is_expected.to be_a DaruLite::Vector }
211
+ its(:size) { is_expected.to eq 2 }
212
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
213
+ its(:index) { is_expected.to eq(
214
+ DaruLite::CategoricalIndex.new([1, 1])) }
215
+ end
216
+
217
+ context "single instance" do
218
+ subject { dv[3] }
219
+
220
+ it { is_expected.to eq 'e' }
221
+ end
222
+ end
223
+ end
224
+ end
225
+ end
226
+
227
+ describe "#at" do
228
+ context DaruLite::Index do
229
+ let (:idx) { DaruLite::Index.new [1, 0, :c] }
230
+ let (:dv) { DaruLite::Vector.new ['a', 'b', 'c'], index: idx }
231
+
232
+ let (:idx_dt) { DaruLite::DateTimeIndex.new(['2017-01-01', '2017-02-01', '2017-03-01']) }
233
+ let (:dv_dt) { DaruLite::Vector.new(['a', 'b', 'c'], index: idx_dt) }
234
+
235
+ context "single position" do
236
+ it { expect(dv.at 1).to eq 'b' }
237
+ end
238
+
239
+ context "multiple positions" do
240
+ subject { dv.at 0, 2 }
241
+
242
+ it { is_expected.to be_a DaruLite::Vector }
243
+ its(:size) { is_expected.to eq 2 }
244
+ its(:to_a) { is_expected.to eq ['a', 'c'] }
245
+ its(:'index.to_a') { is_expected.to eq [1, :c] }
246
+ end
247
+
248
+ context "invalid position" do
249
+ it { expect { dv.at 3 }.to raise_error IndexError }
250
+ end
251
+
252
+ context "invalid positions" do
253
+ it { expect { dv.at 2, 3 }.to raise_error IndexError }
254
+ end
255
+
256
+ context "range" do
257
+ subject { dv.at 0..1 }
258
+
259
+ it { is_expected.to be_a DaruLite::Vector }
260
+ its(:size) { is_expected.to eq 2 }
261
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
262
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
263
+ end
264
+
265
+ context "range with negative end" do
266
+ subject { dv.at 0..-2 }
267
+
268
+ it { is_expected.to be_a DaruLite::Vector }
269
+ its(:size) { is_expected.to eq 2 }
270
+ its(:to_a) { is_expected.to eq ['a', 'b'] }
271
+ its(:'index.to_a') { is_expected.to eq [1, 0] }
272
+ end
273
+
274
+ context "range with single element" do
275
+ subject { dv.at 0..0 }
276
+
277
+ it { is_expected.to be_a DaruLite::Vector }
278
+ its(:size) { is_expected.to eq 1 }
279
+ its(:to_a) { is_expected.to eq ['a'] }
280
+ its(:'index.to_a') { is_expected.to eq [1] }
281
+ end
282
+
283
+ context "Splat .at on DateTime index" do
284
+ subject { dv_dt.at(*[1,2]) }
285
+
286
+ it { is_expected.to be_a DaruLite::Vector }
287
+ its(:size) { is_expected.to eq 2 }
288
+ its(:to_a) { is_expected.to eq ['b', 'c'] }
289
+ its(:'index.to_a') { is_expected.to eq ['2017-02-01', '2017-03-01'] }
290
+ end
291
+ end
292
+
293
+ context DaruLite::MultiIndex do
294
+ let (:idx) do
295
+ DaruLite::MultiIndex.from_tuples [
296
+ [:a,:one,:bar],
297
+ [:a,:one,:baz],
298
+ [:b,:two,:bar],
299
+ [:a,:two,:baz],
300
+ ]
301
+ end
302
+ let (:dv) { DaruLite::Vector.new 1..4, index: idx }
303
+
304
+ context "single position" do
305
+ it { expect(dv.at 1).to eq 2 }
306
+ end
307
+
308
+ context "multiple positions" do
309
+ subject { dv.at 2, 3 }
310
+
311
+ it { is_expected.to be_a DaruLite::Vector }
312
+ its(:size) { is_expected.to eq 2 }
313
+ its(:to_a) { is_expected.to eq [3, 4] }
314
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
315
+ [:a, :two, :baz]] }
316
+ end
317
+
318
+ context "invalid position" do
319
+ it { expect { dv.at 4 }.to raise_error IndexError }
320
+ end
321
+
322
+ context "invalid positions" do
323
+ it { expect { dv.at 2, 4 }.to raise_error IndexError }
324
+ end
325
+
326
+ context "range" do
327
+ subject { dv.at 2..3 }
328
+
329
+ it { is_expected.to be_a DaruLite::Vector }
330
+ its(:size) { is_expected.to eq 2 }
331
+ its(:to_a) { is_expected.to eq [3, 4] }
332
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
333
+ [:a, :two, :baz]] }
334
+ end
335
+
336
+ context "range with negative end" do
337
+ subject { dv.at 2..-1 }
338
+
339
+ it { is_expected.to be_a DaruLite::Vector }
340
+ its(:size) { is_expected.to eq 2 }
341
+ its(:to_a) { is_expected.to eq [3, 4] }
342
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar],
343
+ [:a, :two, :baz]] }
344
+ end
345
+
346
+ context "range with single element" do
347
+ subject { dv.at 2..2 }
348
+
349
+ it { is_expected.to be_a DaruLite::Vector }
350
+ its(:size) { is_expected.to eq 1 }
351
+ its(:to_a) { is_expected.to eq [3] }
352
+ its(:'index.to_a') { is_expected.to eq [[:b, :two, :bar]] }
353
+ end
354
+ end
355
+
356
+ context DaruLite::CategoricalIndex do
357
+ let (:idx) { DaruLite::CategoricalIndex.new [:a, 1, 1, :a, :c] }
358
+ let (:dv) { DaruLite::Vector.new 'a'..'e', index: idx }
359
+
360
+ context "multiple positional indexes" do
361
+ subject { dv.at 0, 1, 2 }
362
+
363
+ it { is_expected.to be_a DaruLite::Vector }
364
+ its(:size) { is_expected.to eq 3 }
365
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
366
+ its(:index) { is_expected.to eq(
367
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
368
+ end
369
+
370
+ context "single positional index" do
371
+ subject { dv.at 1 }
372
+
373
+ it { is_expected.to eq 'b' }
374
+ end
375
+
376
+ context "invalid position" do
377
+ it { expect { dv.at 5 }.to raise_error IndexError }
378
+ end
379
+
380
+ context "invalid positions" do
381
+ it { expect { dv.at 2, 5 }.to raise_error IndexError }
382
+ end
383
+
384
+ context "range" do
385
+ subject { dv.at 0..2 }
386
+
387
+ it { is_expected.to be_a DaruLite::Vector }
388
+ its(:size) { is_expected.to eq 3 }
389
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
390
+ its(:index) { is_expected.to eq(
391
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
392
+ end
393
+
394
+ context "range with negative end" do
395
+ subject { dv.at 0..-3 }
396
+
397
+ it { is_expected.to be_a DaruLite::Vector }
398
+ its(:size) { is_expected.to eq 3 }
399
+ its(:to_a) { is_expected.to eq ['a', 'b', 'c'] }
400
+ its(:index) { is_expected.to eq(
401
+ DaruLite::CategoricalIndex.new([:a, 1, 1])) }
402
+ end
403
+
404
+ context "range with single element" do
405
+ subject { dv.at 0..0 }
406
+
407
+ it { is_expected.to be_a DaruLite::Vector }
408
+ its(:size) { is_expected.to eq 1 }
409
+ its(:to_a) { is_expected.to eq ['a'] }
410
+ its(:index) { is_expected.to eq(
411
+ DaruLite::CategoricalIndex.new([:a])) }
412
+ end
413
+ end
414
+ end
415
+
416
+ describe '#head' do
417
+ subject(:vector) { DaruLite::Vector.new (1..20).to_a, dtype: }
418
+
419
+ it 'takes 10 by default' do
420
+ expect(vector.head).to eq DaruLite::Vector.new (1..10).to_a
421
+ end
422
+
423
+ it 'takes num if provided' do
424
+ expect(vector.head(3)).to eq DaruLite::Vector.new (1..3).to_a
425
+ end
426
+
427
+ it 'does not fail on too large num' do
428
+ expect(vector.head(3000)).to eq vector
429
+ end
430
+ end
431
+
432
+ describe '#tail' do
433
+ subject(:vector) { DaruLite::Vector.new (1..20).to_a, dtype: }
434
+
435
+ it 'takes 10 by default' do
436
+ expect(vector.tail).to eq DaruLite::Vector.new (11..20).to_a, index: (10..19).to_a
437
+ end
438
+
439
+ it 'takes num if provided' do
440
+ expect(vector.tail(3)).to eq DaruLite::Vector.new (18..20).to_a, index: (17..19).to_a
441
+ end
442
+
443
+ it 'does not fail on too large num' do
444
+ expect(vector.tail(3000)).to eq vector
445
+ end
446
+ end
447
+
448
+ describe '#last' do
449
+ subject(:vector) { DaruLite::Vector.new (1..20).to_a, dtype: }
450
+
451
+ it 'takes 1 by default' do
452
+ expect(vector.last).to eq 20
453
+ end
454
+
455
+ it 'takes num if provided' do
456
+ expect(vector.last(3)).to eq DaruLite::Vector.new (18..20).to_a, index: (17..19).to_a
457
+ end
458
+
459
+ it 'does not fail on too large num' do
460
+ expect(vector.last(3000)).to eq vector
461
+ end
462
+ end
463
+ end
@@ -0,0 +1,165 @@
1
+ shared_examples_for 'a filterable Vector' do |dtype|
2
+ let(:vector) do
3
+ DaruLite::Vector.new([1, 22, 33, 45, 65, 32, 524, 656, 123, 99, 77], dtype:)
4
+ end
5
+
6
+ describe "#delete_if" do
7
+ subject { vector.delete_if { |d| d % 11 == 0 } }
8
+
9
+ it "deletes elements if block evaluates to true" do
10
+ expect(subject).to eq(
11
+ DaruLite::Vector.new(
12
+ [1, 45, 65, 32, 524, 656, 123],
13
+ index: [0, 3, 4, 5, 6, 7, 8],
14
+ dtype:
15
+ )
16
+ )
17
+ end
18
+
19
+ it 'does not change dtype' do
20
+ expect(subject.dtype).to eq(dtype)
21
+ end
22
+ end
23
+
24
+ describe "#keep_if" do
25
+ subject { vector.keep_if { |d| d < 35 } }
26
+
27
+ it "keeps elements if block returns true" do
28
+ expect(subject).to eq(
29
+ DaruLite::Vector.new(
30
+ [1, 22, 33, 32],
31
+ index: [0, 1, 2, 5],
32
+ dtype:
33
+ )
34
+ )
35
+ end
36
+
37
+ it 'does not change dtype' do
38
+ expect(subject.dtype).to eq(dtype)
39
+ end
40
+ end
41
+
42
+ describe "#uniq" do
43
+ subject { vector.uniq }
44
+
45
+ let(:vector) do
46
+ DaruLite::Vector.new([1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f])
47
+ end
48
+
49
+ it "keeps only unique values" do
50
+ expect(subject).to eq(DaruLite::Vector.new [1, 2, 2.0, 3, 3.0], index: [:a, :b, :d, :e, :f])
51
+ end
52
+ end
53
+
54
+ describe '#reject_values'do
55
+ let(:vector) do
56
+ DaruLite::Vector.new(
57
+ [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1],
58
+ index: 11..18
59
+ )
60
+ end
61
+
62
+ context 'reject only nils' do
63
+ subject { vector.reject_values nil }
64
+
65
+ it { is_expected.to be_a DaruLite::Vector }
66
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
67
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
68
+ end
69
+
70
+ context 'reject only float::NAN' do
71
+ subject { vector.reject_values Float::NAN }
72
+
73
+ it { is_expected.to be_a DaruLite::Vector }
74
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
75
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
76
+ end
77
+
78
+ context 'reject both nil and float::NAN' do
79
+ subject { vector.reject_values nil, Float::NAN }
80
+
81
+ it { is_expected.to be_a DaruLite::Vector }
82
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
83
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
84
+ end
85
+
86
+ context 'reject any other value' do
87
+ subject { vector.reject_values 1, 3 }
88
+
89
+ it { is_expected.to be_a DaruLite::Vector }
90
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
91
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
92
+ end
93
+
94
+ context 'when resultant vector has only one value' do
95
+ subject { vector.reject_values 1, :a, nil, Float::NAN }
96
+
97
+ it { is_expected.to be_a DaruLite::Vector }
98
+ its(:to_a) { is_expected.to eq [3] }
99
+ its(:'index.to_a') { is_expected.to eq [13] }
100
+ end
101
+
102
+ context 'when resultant vector has no value' do
103
+ subject { vector.reject_values 1, 3, :a, nil, Float::NAN, 5 }
104
+
105
+ it { is_expected.to be_a DaruLite::Vector }
106
+ its(:to_a) { is_expected.to eq [] }
107
+ its(:'index.to_a') { is_expected.to eq [] }
108
+ end
109
+
110
+ context 'test caching' do
111
+ let(:vector) { DaruLite::Vector.new [nil]*8, index: 11..18}
112
+
113
+ before do
114
+ vector.reject_values nil
115
+ [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1].each_with_index do |v, pos|
116
+ vector.set_at [pos], v
117
+ end
118
+ end
119
+
120
+ context 'reject only nils' do
121
+ subject { vector.reject_values nil }
122
+
123
+ it { is_expected.to be_a DaruLite::Vector }
124
+ its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
125
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
126
+ end
127
+
128
+ context 'reject only float::NAN' do
129
+ subject { vector.reject_values Float::NAN }
130
+
131
+ it { is_expected.to be_a DaruLite::Vector }
132
+ its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
133
+ its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
134
+ end
135
+
136
+ context 'reject both nil and float::NAN' do
137
+ subject { vector.reject_values nil, Float::NAN }
138
+
139
+ it { is_expected.to be_a DaruLite::Vector }
140
+ its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
141
+ its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
142
+ end
143
+
144
+ context 'reject any other value' do
145
+ subject { vector.reject_values 1, 3 }
146
+
147
+ it { is_expected.to be_a DaruLite::Vector }
148
+ its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
149
+ its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
150
+ end
151
+ end
152
+ end
153
+
154
+ context "#only_numerics" do
155
+ subject { vector.only_numerics }
156
+
157
+ let(:vector) { DaruLite::Vector.new([1, 2, nil, 3, 4, 's', 'a', nil]) }
158
+
159
+ it "returns only numerical or missing data" do
160
+ expect(subject).to eq(
161
+ DaruLite::Vector.new([1, 2, nil, 3, 4, nil], index: [0, 1, 2, 3, 4, 7])
162
+ )
163
+ end
164
+ end
165
+ end