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,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
|