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.
- 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 +14 -1
- data/lib/daru_lite/index/multi_index.rb +9 -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 +409 -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/categorical_index_spec.rb +27 -8
- data/spec/index/index_spec.rb +21 -0
- data/spec/index/multi_index_spec.rb +85 -76
- 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
@@ -1,36 +1,47 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe DaruLite::CategoricalIndex do
|
4
|
+
let(:index) { described_class.new(keys) }
|
5
|
+
let(:keys) { [:a, :b, :a, :a, :c] }
|
6
|
+
|
7
|
+
describe "#to_a" do
|
8
|
+
subject { index.to_a }
|
9
|
+
|
10
|
+
it { is_expected.to eq(keys) }
|
11
|
+
|
12
|
+
it 'the returns array is not a variable of the index' do
|
13
|
+
expect { subject << 'four' }.not_to change { index.to_a }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
4
17
|
context "#pos" do
|
5
18
|
context "when the category is non-numeric" do
|
6
|
-
let(:idx) { described_class.new [:a, :b, :a, :a, :c] }
|
7
|
-
|
8
19
|
context "single category" do
|
9
|
-
subject {
|
20
|
+
subject { index.pos :a }
|
10
21
|
|
11
22
|
it { is_expected.to eq [0, 2, 3] }
|
12
23
|
end
|
13
24
|
|
14
25
|
context "multiple categories" do
|
15
|
-
subject {
|
26
|
+
subject { index.pos :a, :c }
|
16
27
|
|
17
28
|
it { is_expected.to eq [0, 2, 3, 4] }
|
18
29
|
end
|
19
30
|
|
20
31
|
context "invalid category" do
|
21
|
-
it { expect {
|
32
|
+
it { expect { index.pos :e }.to raise_error IndexError }
|
22
33
|
end
|
23
34
|
|
24
35
|
context "positional index" do
|
25
|
-
it { expect(
|
36
|
+
it { expect(index.pos 0).to eq 0 }
|
26
37
|
end
|
27
38
|
|
28
39
|
context "invalid positional index" do
|
29
|
-
it { expect {
|
40
|
+
it { expect { index.pos 5 }.to raise_error IndexError }
|
30
41
|
end
|
31
42
|
|
32
43
|
context "multiple positional indexes" do
|
33
|
-
subject {
|
44
|
+
subject { index.pos 0, 1, 2 }
|
34
45
|
|
35
46
|
it { is_expected.to be_a Array }
|
36
47
|
its(:size) { is_expected.to eq 3 }
|
@@ -167,4 +178,12 @@ describe DaruLite::CategoricalIndex do
|
|
167
178
|
it { expect(idx.valid? :a, 1, 5).to eq false }
|
168
179
|
end
|
169
180
|
end
|
181
|
+
|
182
|
+
describe '#delete_at' do
|
183
|
+
subject { index.delete_at(3) }
|
184
|
+
|
185
|
+
let(:index) { described_class.new([:a, 1, :a, 1, 'c']) }
|
186
|
+
|
187
|
+
it { is_expected.to eq(described_class.new([:a, 1, :a, 'c'])) }
|
188
|
+
end
|
170
189
|
end
|
data/spec/index/index_spec.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe DaruLite::Index do
|
4
|
+
let(:index) { described_class.new(keys) }
|
5
|
+
let(:keys) { ['one', 'two', 'three'] }
|
6
|
+
|
4
7
|
context ".new" do
|
5
8
|
it "creates an Index object if Index-like data is supplied" do
|
6
9
|
i = DaruLite::Index.new [:one, 'one', 1, 2, :two]
|
@@ -147,6 +150,16 @@ describe DaruLite::Index do
|
|
147
150
|
end
|
148
151
|
end
|
149
152
|
|
153
|
+
describe "#to_a" do
|
154
|
+
subject { index.to_a }
|
155
|
+
|
156
|
+
it { is_expected.to eq(keys) }
|
157
|
+
|
158
|
+
it 'the returns array is not a variable of the index' do
|
159
|
+
expect { subject << 'four' }.not_to change { index.to_a }
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
150
163
|
context "#&" do
|
151
164
|
before :each do
|
152
165
|
@left = DaruLite::Index.new [:miles, :geddy, :eric]
|
@@ -389,6 +402,14 @@ describe DaruLite::Index do
|
|
389
402
|
|
390
403
|
end
|
391
404
|
|
405
|
+
describe '#delete_at' do
|
406
|
+
subject { index.delete_at(1) }
|
407
|
+
|
408
|
+
let(:index) { described_class.new([:a, :b, 1, 2]) }
|
409
|
+
|
410
|
+
it { is_expected.to eq(described_class.new([:a, 1, 2])) }
|
411
|
+
end
|
412
|
+
|
392
413
|
context '#to_df' do
|
393
414
|
let(:idx) do
|
394
415
|
DaruLite::Index.new(['speaker', 'mic', 'guitar', 'amp'],
|
@@ -1,22 +1,22 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe DaruLite::MultiIndex do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
[:a
|
8
|
-
[:a
|
9
|
-
[:a
|
10
|
-
[:
|
11
|
-
[:b
|
12
|
-
[:b
|
13
|
-
[:b
|
14
|
-
[:
|
15
|
-
[:c
|
16
|
-
[:c
|
17
|
-
[:c
|
4
|
+
let(:index) { described_class.from_tuples(index_tuples) }
|
5
|
+
let(:index_tuples) do
|
6
|
+
[
|
7
|
+
[:a, :one, :bar],
|
8
|
+
[:a, :one, :baz],
|
9
|
+
[:a, :two, :bar],
|
10
|
+
[:a, :two, :baz],
|
11
|
+
[:b, :one, :bar],
|
12
|
+
[:b, :two, :bar],
|
13
|
+
[:b, :two, :baz],
|
14
|
+
[:b, :one, :foo],
|
15
|
+
[:c, :one, :bar],
|
16
|
+
[:c, :one, :baz],
|
17
|
+
[:c, :two, :foo],
|
18
|
+
[:c, :two, :bar]
|
18
19
|
]
|
19
|
-
@multi_mi = DaruLite::MultiIndex.from_tuples(@index_tuples)
|
20
20
|
end
|
21
21
|
|
22
22
|
context ".initialize" do
|
@@ -71,16 +71,16 @@ describe DaruLite::MultiIndex do
|
|
71
71
|
|
72
72
|
it "raises SizeError for wrong number of name" do
|
73
73
|
error_msg = "\'names\' and \'levels\' should be of same size. Size of the \'name\' array is 2 and size of the MultiIndex \'levels\' and \'labels\' is 3.\nIf you do not want to set name for particular level (say level \'i\') then put empty string on index \'i\' of the \'name\' Array."
|
74
|
-
expect {
|
74
|
+
expect { index.name = ['n1', 'n2'] }.to raise_error(SizeError, error_msg)
|
75
75
|
|
76
76
|
error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 0 and size of the MultiIndex 'levels' and 'labels' is 3.\nIf you do not want to set name for particular level (say level 'i') then put empty string on index 'i' of the 'name' Array."
|
77
|
-
expect {
|
77
|
+
expect { index.name = [ ] }.to raise_error(SizeError, error_msg)
|
78
78
|
|
79
79
|
error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 1 and size of the MultiIndex 'levels' and 'labels' is 3.\nIf you do not want to set name for particular level (say level 'i') then put empty string on index 'i' of the 'name' Array."
|
80
|
-
expect {
|
80
|
+
expect { index.name = [''] }.to raise_error(SizeError, error_msg)
|
81
81
|
|
82
82
|
error_msg = "'names' and 'levels' should be of same size. Size of the 'name' array is 4 and size of the MultiIndex 'levels' and 'labels' is 3."
|
83
|
-
expect {
|
83
|
+
expect { index.name = ['n1', 'n2', 'n3', 'n4'] }.to raise_error(SizeError, error_msg)
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -101,8 +101,8 @@ describe DaruLite::MultiIndex do
|
|
101
101
|
end
|
102
102
|
|
103
103
|
it "creates a triple layer MultiIndex from tuples" do
|
104
|
-
expect(
|
105
|
-
expect(
|
104
|
+
expect(index.levels).to eq([[:a,:b,:c], [:one, :two],[:bar,:baz,:foo]])
|
105
|
+
expect(index.labels).to eq([
|
106
106
|
[0,0,0,0,1,1,1,1,2,2,2,2],
|
107
107
|
[0,0,1,1,0,1,1,0,0,0,1,1],
|
108
108
|
[0,1,0,1,0,0,1,2,0,1,2,0]
|
@@ -132,23 +132,23 @@ describe DaruLite::MultiIndex do
|
|
132
132
|
|
133
133
|
context "#size" do
|
134
134
|
it "returns size of MultiIndex" do
|
135
|
-
expect(
|
135
|
+
expect(index.size).to eq(12)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
139
|
context "#[]" do
|
140
140
|
it "returns the row number when specifying the complete tuple" do
|
141
|
-
expect(
|
141
|
+
expect(index[:a, :one, :baz]).to eq(1)
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns MultiIndex when specifying incomplete tuple" do
|
145
|
-
expect(
|
145
|
+
expect(index[:b]).to eq(DaruLite::MultiIndex.from_tuples([
|
146
146
|
[:b,:one,:bar],
|
147
147
|
[:b,:two,:bar],
|
148
148
|
[:b,:two,:baz],
|
149
149
|
[:b,:one,:foo]
|
150
150
|
]))
|
151
|
-
expect(
|
151
|
+
expect(index[:b, :one]).to eq(DaruLite::MultiIndex.from_tuples([
|
152
152
|
[:b,:one,:bar],
|
153
153
|
[:b,:one,:foo]
|
154
154
|
]))
|
@@ -156,7 +156,7 @@ describe DaruLite::MultiIndex do
|
|
156
156
|
end
|
157
157
|
|
158
158
|
it "returns MultiIndex when specifying wholly numeric ranges" do
|
159
|
-
expect(
|
159
|
+
expect(index[3..6]).to eq(DaruLite::MultiIndex.from_tuples([
|
160
160
|
[:a,:two,:baz],
|
161
161
|
[:b,:one,:bar],
|
162
162
|
[:b,:two,:bar],
|
@@ -165,11 +165,11 @@ describe DaruLite::MultiIndex do
|
|
165
165
|
end
|
166
166
|
|
167
167
|
it "raises error when specifying invalid index" do
|
168
|
-
expect {
|
169
|
-
expect {
|
170
|
-
expect {
|
171
|
-
expect {
|
172
|
-
expect {
|
168
|
+
expect { index[:a, :three] }.to raise_error IndexError
|
169
|
+
expect { index[:a, :one, :xyz] }.to raise_error IndexError
|
170
|
+
expect { index[:x] }.to raise_error IndexError
|
171
|
+
expect { index[:x, :one] }.to raise_error IndexError
|
172
|
+
expect { index[:x, :one, :bar] }.to raise_error IndexError
|
173
173
|
end
|
174
174
|
|
175
175
|
it "works with numerical first levels" do
|
@@ -189,93 +189,89 @@ describe DaruLite::MultiIndex do
|
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
+
describe "#to_a" do
|
193
|
+
subject { index.to_a }
|
194
|
+
|
195
|
+
it { is_expected.to eq(index_tuples) }
|
196
|
+
|
197
|
+
it 'the returns array is not a variable of the index' do
|
198
|
+
expect { subject << [:d, :one, :bar] }.not_to change { index.to_a }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
192
202
|
context "#include?" do
|
193
203
|
it "checks if a completely specified tuple exists" do
|
194
|
-
expect(
|
204
|
+
expect(index.include?([:a,:one,:bar])).to eq(true)
|
195
205
|
end
|
196
206
|
|
197
207
|
it "checks if a top layer incomplete tuple exists" do
|
198
|
-
expect(
|
208
|
+
expect(index.include?([:a])).to eq(true)
|
199
209
|
end
|
200
210
|
|
201
211
|
it "checks if a middle layer incomplete tuple exists" do
|
202
|
-
expect(
|
212
|
+
expect(index.include?([:a, :one])).to eq(true)
|
203
213
|
end
|
204
214
|
|
205
215
|
it "checks for non-existence of completely specified tuple" do
|
206
|
-
expect(
|
216
|
+
expect(index.include?([:b, :two, :foo])).to eq(false)
|
207
217
|
end
|
208
218
|
|
209
219
|
it "checks for non-existence of a top layer incomplete tuple" do
|
210
|
-
expect(
|
220
|
+
expect(index.include?([:d])).to eq(false)
|
211
221
|
end
|
212
222
|
|
213
223
|
it "checks for non-existence of a middle layer incomplete tuple" do
|
214
|
-
expect(
|
224
|
+
expect(index.include?([:c, :three])).to eq(false)
|
215
225
|
end
|
216
226
|
end
|
217
227
|
|
218
228
|
context "#key" do
|
219
229
|
it "returns the tuple of the specified number" do
|
220
|
-
expect(
|
230
|
+
expect(index.key(3)).to eq([:a,:two,:baz])
|
221
231
|
end
|
222
232
|
|
223
233
|
it "returns nil for non-existent pointer number" do
|
224
234
|
expect {
|
225
|
-
|
235
|
+
index.key(100)
|
226
236
|
}.to raise_error ArgumentError
|
227
237
|
end
|
228
238
|
end
|
229
239
|
|
230
240
|
context "#to_a" do
|
231
241
|
it "returns tuples as an Array" do
|
232
|
-
expect(
|
242
|
+
expect(index.to_a).to eq(index_tuples)
|
233
243
|
end
|
234
244
|
end
|
235
245
|
|
236
246
|
context "#dup" do
|
237
247
|
it "completely duplicates the object" do
|
238
|
-
duplicate =
|
239
|
-
expect(duplicate) .to eq(
|
240
|
-
expect(duplicate.object_id).to_not eq(
|
248
|
+
duplicate = index.dup
|
249
|
+
expect(duplicate) .to eq(index)
|
250
|
+
expect(duplicate.object_id).to_not eq(index.object_id)
|
241
251
|
end
|
242
252
|
end
|
243
253
|
|
244
254
|
context "#inspect" do
|
245
255
|
context 'small index' do
|
246
|
-
subject {
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
its(:inspect) { is_expected.to eq %Q{
|
264
|
-
|#<DaruLite::MultiIndex(12x3)>
|
265
|
-
| a one bar
|
266
|
-
| baz
|
267
|
-
| two bar
|
268
|
-
| baz
|
269
|
-
| b one bar
|
270
|
-
| two bar
|
271
|
-
| baz
|
272
|
-
| one foo
|
273
|
-
| c one bar
|
274
|
-
| baz
|
275
|
-
| two foo
|
276
|
-
| bar
|
256
|
+
subject { index.inspect }
|
257
|
+
|
258
|
+
it do
|
259
|
+
is_expected.to eq %Q{
|
260
|
+
|#<DaruLite::MultiIndex(12x3)>
|
261
|
+
| a one bar
|
262
|
+
| baz
|
263
|
+
| two bar
|
264
|
+
| baz
|
265
|
+
| b one bar
|
266
|
+
| two bar
|
267
|
+
| baz
|
268
|
+
| one foo
|
269
|
+
| c one bar
|
270
|
+
| baz
|
271
|
+
| two foo
|
272
|
+
| bar
|
277
273
|
}.unindent
|
278
|
-
|
274
|
+
end
|
279
275
|
end
|
280
276
|
|
281
277
|
context 'large index' do
|
@@ -331,7 +327,7 @@ describe DaruLite::MultiIndex do
|
|
331
327
|
|
332
328
|
context 'multi index with name having empty string' do
|
333
329
|
subject {
|
334
|
-
|
330
|
+
DaruLite::MultiIndex.new(
|
335
331
|
levels: [[:a,:b,:c],[:one,:two],[:bar, :baz, :foo]],
|
336
332
|
labels: [
|
337
333
|
[0,0,0,0,1,1,1,1,2,2,2,2],
|
@@ -677,4 +673,17 @@ describe DaruLite::MultiIndex do
|
|
677
673
|
'col3' => %w[bar bar baz foo]
|
678
674
|
)}
|
679
675
|
end
|
676
|
+
|
677
|
+
describe '#delete_at' do
|
678
|
+
subject { index.delete_at(3)}
|
679
|
+
|
680
|
+
let(:index) do
|
681
|
+
DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:b, :two], [:c, :one]])
|
682
|
+
end
|
683
|
+
let(:expected_index) do
|
684
|
+
DaruLite::MultiIndex.from_tuples([[:a, :one], [:a, :two], [:b, :one], [:c, :one]])
|
685
|
+
end
|
686
|
+
|
687
|
+
it { is_expected.to eq(expected_index) }
|
688
|
+
end
|
680
689
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
shared_examples_for 'an aggregatable Vector' do
|
2
|
+
context "#group_by" do
|
3
|
+
let(:dv) { DaruLite::Vector.new [:a, :b, :a, :b, :c] }
|
4
|
+
|
5
|
+
context 'vector not specified' do
|
6
|
+
subject { dv.group_by }
|
7
|
+
|
8
|
+
it { is_expected.to be_a DaruLite::Core::GroupBy }
|
9
|
+
its(:'groups.size') { is_expected.to eq 3 }
|
10
|
+
its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'vector name specified' do
|
14
|
+
before { dv.name = :hello }
|
15
|
+
subject { dv.group_by :hello }
|
16
|
+
|
17
|
+
it { is_expected.to be_a DaruLite::Core::GroupBy }
|
18
|
+
its(:'groups.size') { is_expected.to eq 3 }
|
19
|
+
its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'vector name invalid' do
|
23
|
+
before { dv.name = :hello }
|
24
|
+
it { expect { dv.group_by :abc }.to raise_error }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
shared_examples_for 'a calculatable Vector' do |dtype|
|
2
|
+
describe '#count_values' do
|
3
|
+
let(:vector) { DaruLite::Vector.new([1, 2, 3, 1, 2, nil, nil]) }
|
4
|
+
|
5
|
+
it { expect(vector.count_values 1, 2).to eq 4 }
|
6
|
+
it { expect(vector.count_values nil).to eq 2 }
|
7
|
+
it { expect(vector.count_values 3, Float::NAN).to eq 1 }
|
8
|
+
it { expect(vector.count_values 4).to eq 0 }
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#summary" do
|
12
|
+
subject { vector.summary }
|
13
|
+
|
14
|
+
context 'all types' do
|
15
|
+
let(:vector) { DaruLite::Vector.new([1 ,2, 3, 4, 5], name: 'vector') }
|
16
|
+
|
17
|
+
it { is_expected.to include vector.name }
|
18
|
+
|
19
|
+
it { is_expected.to include "n :#{vector.size}" }
|
20
|
+
|
21
|
+
it { is_expected.to include "non-missing:#{vector.size - vector.count_values(*DaruLite::MISSING_VALUES)}" }
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
context "numeric type" do
|
26
|
+
let(:vector) { DaruLite::Vector.new([1,2,5], name: 'numeric') }
|
27
|
+
|
28
|
+
it { is_expected. to eq %Q{
|
29
|
+
|= numeric
|
30
|
+
| n :3
|
31
|
+
| non-missing:3
|
32
|
+
| median: 2
|
33
|
+
| mean: 2.6667
|
34
|
+
| std.dev.: 2.0817
|
35
|
+
| std.err.: 1.2019
|
36
|
+
| skew: 0.2874
|
37
|
+
| kurtosis: -2.3333
|
38
|
+
}.unindent }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "numeric type with missing values" do
|
42
|
+
let(:vector) { DaruLite::Vector.new([1,2,5,nil,Float::NAN], name: 'numeric') }
|
43
|
+
|
44
|
+
it { is_expected.not_to include 'skew' }
|
45
|
+
it { is_expected.not_to include 'kurtosis' }
|
46
|
+
end
|
47
|
+
|
48
|
+
if dtype == :array
|
49
|
+
context "object type" do
|
50
|
+
let(:vector) { DaruLite::Vector.new([1, 1, 2, 2, "string", nil, Float::NAN], name: 'object') }
|
51
|
+
|
52
|
+
if RUBY_VERSION >= '2.2'
|
53
|
+
it { is_expected.to eq %Q{
|
54
|
+
|= object
|
55
|
+
| n :7
|
56
|
+
| non-missing:5
|
57
|
+
| factors: 1,2,string
|
58
|
+
| mode: 1,2
|
59
|
+
| Distribution
|
60
|
+
| string 1 50.00%
|
61
|
+
| NaN 1 50.00%
|
62
|
+
| 1 2 100.00%
|
63
|
+
| 2 2 100.00%
|
64
|
+
}.unindent }
|
65
|
+
else
|
66
|
+
it { is_expected.to eq %Q{
|
67
|
+
|= object
|
68
|
+
| n :7
|
69
|
+
| non-missing:5
|
70
|
+
| factors: 1,2,string
|
71
|
+
| mode: 1,2
|
72
|
+
| Distribution
|
73
|
+
| NaN 1 50.00%
|
74
|
+
| string 1 50.00%
|
75
|
+
| 2 2 100.00%
|
76
|
+
| 1 2 100.00%
|
77
|
+
}.unindent }
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
shared_examples_for 'a convertible Vector' do |dtype|
|
2
|
+
describe "#to_df" do
|
3
|
+
subject { vector.to_df }
|
4
|
+
|
5
|
+
let(:vector) do
|
6
|
+
DaruLite::Vector.new(['a','b','c'], name: :my_dv, index: ['alpha', 'beta', 'gamma'])
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'is a dataframe' do
|
10
|
+
expect(subject).to be_a DaruLite::DataFrame
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'converts the vector to a single-vector dataframe' do
|
14
|
+
expect(subject[:my_dv]).to eq vector
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'has the same index as the original vector' do
|
18
|
+
expect(subject.index).to eq vector.index
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has the same name as the vector' do
|
22
|
+
expect(subject.name).to eq :my_dv
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#to_h" do
|
27
|
+
context DaruLite::Index do
|
28
|
+
subject { vector.to_h }
|
29
|
+
|
30
|
+
let(:vector) do
|
31
|
+
DaruLite::Vector.new(
|
32
|
+
[1,2,3,4,5],
|
33
|
+
name: :a,
|
34
|
+
index: [:one, :two, :three, :four, :five],
|
35
|
+
dtype:
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns the vector as a hash" do
|
40
|
+
expect(subject).to eq({one: 1, two: 2, three: 3, four: 4, five: 5})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context DaruLite::MultiIndex do
|
45
|
+
pending
|
46
|
+
# it "returns vector as a Hash" do
|
47
|
+
# pending
|
48
|
+
# mi = DaruLite::MultiIndex.from_tuples([
|
49
|
+
# [:a,:two,:bar],
|
50
|
+
# [:a,:two,:baz],
|
51
|
+
# [:b,:one,:bar],
|
52
|
+
# [:b,:two,:bar]
|
53
|
+
# ])
|
54
|
+
# vector = DaruLite::Vector.new([1,2,3,4], index: mi, dtype: dtype)
|
55
|
+
# expect(vector.to_h).to eq({
|
56
|
+
# [:a,:two,:bar] => 1,
|
57
|
+
# [:a,:two,:baz] => 2,
|
58
|
+
# [:b,:one,:bar] => 3,
|
59
|
+
# [:b,:two,:bar] => 4
|
60
|
+
# })
|
61
|
+
# end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#to_json" do
|
66
|
+
subject { vector.to_json }
|
67
|
+
|
68
|
+
let(:vector) do
|
69
|
+
DaruLite::Vector.new(
|
70
|
+
[1,2,3,4,5],
|
71
|
+
name: :a,
|
72
|
+
index: [:one, :two, :three, :four, :five],
|
73
|
+
dtype: dtype
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "returns the vector as json" do
|
78
|
+
expect(subject).to eq(vector.to_h.to_json)
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#to_s" do
|
84
|
+
let(:vector) { DaruLite::Vector.new(["a", "b"], index: [1, 2], name:) }
|
85
|
+
|
86
|
+
context 'name is nil' do
|
87
|
+
let(:name) { nil }
|
88
|
+
|
89
|
+
it 'produces a class, size description' do
|
90
|
+
expect(vector.to_s).to eq("#<DaruLite::Vector(2)>")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'name is present' do
|
95
|
+
let(:name) { "Test" }
|
96
|
+
|
97
|
+
it 'produces a class, name, size description' do
|
98
|
+
expect(vector.to_s).to eq("#<DaruLite::Vector: Test(2)>")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'name is a symbol' do
|
103
|
+
let(:name) { :Test }
|
104
|
+
|
105
|
+
it 'produces a class, name, size description' do
|
106
|
+
expect(vector.to_s).to eq("#<DaruLite::Vector: Test(2)>")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#to_matrix" do
|
112
|
+
let(:vector) { DaruLite::Vector.new [1, 2, 3, 4, 5, 6] }
|
113
|
+
|
114
|
+
it "converts DaruLite::Vector to a horizontal Ruby Matrix" do
|
115
|
+
expect(vector.to_matrix).to eq(Matrix[[1, 2, 3, 4, 5, 6]])
|
116
|
+
end
|
117
|
+
|
118
|
+
it "converts DaruLite::Vector to a vertical Ruby Matrix" do
|
119
|
+
expect(vector.to_matrix(:vertical)).to eq(Matrix.columns([[1, 2, 3, 4, 5, 6]]))
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'raises on wrong axis' do
|
123
|
+
expect { vector.to_matrix(:strange) }.to raise_error(ArgumentError)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
shared_examples_for 'a duplicatable Vector' do
|
2
|
+
describe "#dup" do
|
3
|
+
subject { vector.dup }
|
4
|
+
|
5
|
+
let(:vector) do
|
6
|
+
DaruLite::Vector.new([1, 2], name: :yoda, index: [:happy, :lightsaber])
|
7
|
+
end
|
8
|
+
|
9
|
+
it "copies the original data" do
|
10
|
+
expect(subject.send(:data)).to eq([1,2])
|
11
|
+
end
|
12
|
+
|
13
|
+
it "creates a new data object" do
|
14
|
+
expect(subject.send(:data).object_id).not_to eq(vector.send(:data).object_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "copies the name" do
|
18
|
+
expect(subject.name).to eq(:yoda)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "copies the original index" do
|
22
|
+
expect(subject.index).to eq(DaruLite::Index.new([:happy, :lightsaber]))
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates a new index object" do
|
26
|
+
expect(subject.index.object_id).not_to eq(vector.index.object_id)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "#clone_structure" do
|
31
|
+
subject { vector.clone_structure }
|
32
|
+
context DaruLite::Index do
|
33
|
+
let(:vector) do
|
34
|
+
DaruLite::Vector.new([1, 2, 3, 4, 5], index: [:a,:b,:c,:d,:e])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "clones a vector with its index and fills it with nils" do
|
38
|
+
expect(subject).to eq(
|
39
|
+
DaruLite::Vector.new([nil, nil, nil, nil, nil], index: [:a,:b,:c,:d,:e])
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context DaruLite::MultiIndex do
|
45
|
+
pending
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|