daru 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +0 -0
  3. data/Gemfile +0 -1
  4. data/History.txt +35 -0
  5. data/README.md +178 -198
  6. data/daru.gemspec +5 -7
  7. data/lib/daru.rb +10 -2
  8. data/lib/daru/accessors/array_wrapper.rb +36 -198
  9. data/lib/daru/accessors/nmatrix_wrapper.rb +60 -209
  10. data/lib/daru/core/group_by.rb +183 -0
  11. data/lib/daru/dataframe.rb +615 -167
  12. data/lib/daru/index.rb +17 -16
  13. data/lib/daru/io/io.rb +5 -12
  14. data/lib/daru/maths/arithmetic/dataframe.rb +72 -8
  15. data/lib/daru/maths/arithmetic/vector.rb +19 -6
  16. data/lib/daru/maths/statistics/dataframe.rb +103 -2
  17. data/lib/daru/maths/statistics/vector.rb +102 -61
  18. data/lib/daru/monkeys.rb +8 -0
  19. data/lib/daru/multi_index.rb +199 -0
  20. data/lib/daru/plotting/dataframe.rb +24 -24
  21. data/lib/daru/plotting/vector.rb +14 -15
  22. data/lib/daru/vector.rb +402 -98
  23. data/lib/version.rb +1 -1
  24. data/notebooks/grouping_splitting_pivots.ipynb +529 -0
  25. data/notebooks/intro_with_music_data_.ipynb +104 -119
  26. data/spec/accessors/wrappers_spec.rb +36 -0
  27. data/spec/core/group_by_spec.rb +331 -0
  28. data/spec/dataframe_spec.rb +1237 -475
  29. data/spec/fixtures/sales-funnel.csv +18 -0
  30. data/spec/index_spec.rb +10 -21
  31. data/spec/io/io_spec.rb +4 -14
  32. data/spec/math/arithmetic/dataframe_spec.rb +66 -0
  33. data/spec/math/arithmetic/vector_spec.rb +45 -4
  34. data/spec/math/statistics/dataframe_spec.rb +91 -1
  35. data/spec/math/statistics/vector_spec.rb +32 -6
  36. data/spec/monkeys_spec.rb +10 -1
  37. data/spec/multi_index_spec.rb +216 -0
  38. data/spec/spec_helper.rb +1 -0
  39. data/spec/vector_spec.rb +505 -57
  40. metadata +21 -15
@@ -0,0 +1,216 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe Daru::MultiIndex do
4
+ before(:each) do
5
+ @index_tuples = [
6
+ [:a,:one,:bar],
7
+ [:a,:one,:baz],
8
+ [:a,:two,:bar],
9
+ [:a,:two,:baz],
10
+ [:b,:one,:bar],
11
+ [:b,:two,:bar],
12
+ [:b,:two,:baz],
13
+ [:b,:one,:foo],
14
+ [:c,:one,:bar],
15
+ [:c,:one,:baz],
16
+ [:c,:two,:foo],
17
+ [:c,:two,:bar]
18
+ ]
19
+ @multi_mi = Daru::MultiIndex.new(@index_tuples)
20
+ end
21
+
22
+ context "#initialize" do
23
+ it "creates 2 layer MultiIndex from tuples" do
24
+ tuples = [[:a, :one], [:a, :two], [:b, :one], [:b, :two], [:c, :one], [:c, :two]]
25
+ mi = Daru::MultiIndex.new(tuples)
26
+ expect(mi.relation_hash).to eq({
27
+ :a => {
28
+ :one => 0,
29
+ :two => 1
30
+ },
31
+ :b => {
32
+ :one => 2,
33
+ :two => 3
34
+ },
35
+ :c => {
36
+ :one => 4,
37
+ :two => 5
38
+ }
39
+ })
40
+ end
41
+
42
+ it "creates a triple layer MultiIndex from tuples" do
43
+ expect(@multi_mi.relation_hash).to eq({
44
+ :a => {
45
+ :one => {
46
+ :bar => 0,
47
+ :baz => 1
48
+ },
49
+ :two => {
50
+ :bar => 2,
51
+ :baz => 3
52
+ }
53
+ },
54
+ :b => {
55
+ :one => {
56
+ :bar => 4,
57
+ :foo => 7
58
+ },
59
+ :two => {
60
+ :bar => 5,
61
+ :baz => 6
62
+ }
63
+ },
64
+ :c => {
65
+ :one => {
66
+ :bar => 8,
67
+ :baz => 9
68
+ },
69
+ :two => {
70
+ :foo => 10,
71
+ :bar => 11,
72
+ }
73
+ }
74
+ })
75
+ end
76
+
77
+ it "accepts array index values externally" do
78
+ mi = Daru::MultiIndex.new([
79
+ [:a,:one,:bar],
80
+ [:a,:one,:baz],
81
+ [:a,:two,:bar],
82
+ [:a,:two,:baz],
83
+ [:b,:one,:bar]
84
+ ], [6,3,1,2,9])
85
+
86
+ expect(mi[:a,:two,:baz]).to eq(2)
87
+ end
88
+ end
89
+
90
+ context "#size" do
91
+ it "returns size of MultiIndex" do
92
+ expect(@multi_mi.size).to eq(12)
93
+ end
94
+ end
95
+
96
+ context "#[]" do
97
+ it "returns the row number when specifying the complete tuple" do
98
+ expect(@multi_mi[:a, :one, :baz]).to eq(1)
99
+ end
100
+
101
+ it "returns a MultiIndex when specifying incomplete tuple" do
102
+ expect(@multi_mi[:b]).to eq(Daru::MultiIndex.new([
103
+ [:one,:bar],
104
+ [:two,:bar],
105
+ [:two,:baz],
106
+ [:one,:foo]
107
+ ], [4,5,6,7])
108
+ )
109
+
110
+ expect(@multi_mi[:b, :one]).to eq(Daru::MultiIndex.new([
111
+ [:bar],
112
+ [:foo]
113
+ ], [4,7])
114
+ )
115
+ # TODO: Return Daru::Index if a single layer of indexes is present.
116
+ end
117
+
118
+ it "returns a MultiIndex when specifying as an integer index" do
119
+ expect(@multi_mi[1]).to eq(Daru::MultiIndex.new([
120
+ [:one,:bar],
121
+ [:two,:bar],
122
+ [:two,:baz],
123
+ [:one,:foo]
124
+ ],[4,5,6,7])
125
+ )
126
+ end
127
+
128
+ it "supports numeric Ranges" do
129
+ expect(@multi_mi[0..1]).to eq(Daru::MultiIndex.new([
130
+ [:a,:one,:bar],
131
+ [:a,:one,:baz],
132
+ [:a,:two,:bar],
133
+ [:a,:two,:baz],
134
+ [:b,:one,:bar],
135
+ [:b,:two,:bar],
136
+ [:b,:two,:baz],
137
+ [:b,:one,:foo]
138
+ ]))
139
+ end
140
+ end
141
+
142
+ context "#include?" do
143
+ it "checks if a completely specified tuple exists" do
144
+ expect(@multi_mi.include?([:a,:one,:bar])).to eq(true)
145
+ end
146
+
147
+ it "checks if a top layer incomplete tuple exists" do
148
+ expect(@multi_mi.include?([:a])).to eq(true)
149
+ end
150
+
151
+ it "checks if a middle layer incomplete tuple exists" do
152
+ expect(@multi_mi.include?([:a, :one])).to eq(true)
153
+ end
154
+
155
+ it "checks for non-existence of a tuple" do
156
+ expect(@multi_mi.include?([:boo])).to eq(false)
157
+ end
158
+ end
159
+
160
+ context "#key" do
161
+ it "returns the tuple of the specified number" do
162
+ expect(@multi_mi.key(3)).to eq([:a,:two,:baz])
163
+ end
164
+
165
+ it "returns nil for non-existent pointer number" do
166
+ expect(@multi_mi.key(100)).to eq(nil)
167
+ end
168
+ end
169
+
170
+ context "#to_a" do
171
+ it "returns tuples as an Array" do
172
+ expect(@multi_mi.to_a).to eq(@index_tuples)
173
+ end
174
+ end
175
+
176
+ context "#dup" do
177
+ it "completely duplicates the object" do
178
+ duplicate = @multi_mi.dup
179
+
180
+ expect(duplicate) .to eq(@multi_mi)
181
+ expect(duplicate.object_id).to_not eq(@multi_mi.object_id)
182
+ end
183
+ end
184
+
185
+ context "#==" do
186
+ it "returns false for unequal MultiIndex comparisons" do
187
+ mi1 = Daru::MultiIndex.new([
188
+ [:a, :one, :bar],
189
+ [:a, :two, :baz],
190
+ [:b, :one, :foo],
191
+ [:b, :two, :bar]
192
+ ])
193
+ mi2 = Daru::MultiIndex.new([
194
+ [:a, :two, :bar],
195
+ [:b, :one, :foo],
196
+ [:a, :one, :baz],
197
+ [:b, :two, :baz]
198
+ ])
199
+
200
+ expect(mi1 == mi2).to eq(false)
201
+ end
202
+ end
203
+
204
+ context "#values" do
205
+ it "returns an array of indices in order" do
206
+ mi = Daru::MultiIndex.new([
207
+ [:a, :one, :bar],
208
+ [:a, :two, :baz],
209
+ [:b, :one, :foo],
210
+ [:b, :two, :bar]
211
+ ], [3,5,1,6])
212
+
213
+ expect(mi.values).to eq([3,5,1,6])
214
+ end
215
+ end
216
+ end
@@ -1,5 +1,6 @@
1
1
  require 'rspec'
2
2
  require 'awesome_print'
3
+ require 'matrix'
3
4
 
4
5
  def mri?
5
6
  RUBY_ENGINE == 'ruby'
@@ -1,9 +1,22 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe Daru::Vector do
4
- [Array, NMatrix].each do |dtype|
4
+ ALL_DTYPES = [:array, :nmatrix]
5
+
6
+ ALL_DTYPES.each do |dtype|
5
7
  describe dtype do
6
8
  context "#initialize" do
9
+ before do
10
+ @tuples = [
11
+ [:a, :one, :foo],
12
+ [:a, :two, :bar],
13
+ [:b, :one, :bar],
14
+ [:b, :two, :baz]
15
+ ]
16
+
17
+ @multi_index = Daru::MultiIndex.new(@tuples)
18
+ end
19
+
7
20
  it "initializes from an Array" do
8
21
  dv = Daru::Vector.new [1,2,3,4,5], name: :ravan,
9
22
  index: [:ek, :don, :teen, :char, :pach], dtype: dtype
@@ -14,13 +27,19 @@ describe Daru::Vector do
14
27
 
15
28
  it "accepts Index object" do
16
29
  idx = Daru::Index.new [:yoda, :anakin, :obi, :padme, :r2d2]
17
-
18
30
  dv = Daru::Vector.new [1,2,3,4,5], name: :yoga, index: idx, dtype: dtype
19
31
 
20
32
  expect(dv.name) .to eq(:yoga)
21
33
  expect(dv.index).to eq(idx)
22
34
  end
23
35
 
36
+ it "accepts a MultiIndex object" do
37
+ dv = Daru::Vector.new [1,2,3,4], name: :mi, index: @multi_index, dtype: dtype
38
+
39
+ expect(dv.name).to eq(:mi)
40
+ expect(dv.index).to eq(@multi_index)
41
+ end
42
+
24
43
  it "raises error for improper Index" do
25
44
  expect {
26
45
  dv = Daru::Vector.new [1,2,3,4,5], name: :yoga, index: [:i, :j, :k]
@@ -32,6 +51,12 @@ describe Daru::Vector do
32
51
  }.to raise_error
33
52
  end
34
53
 
54
+ it "raises error for improper MultiIndex" do
55
+ expect {
56
+ dv = Daru::Vector.new [1,2,3,4,5], name: :mi, index: @multi_index
57
+ }.to raise_error
58
+ end
59
+
35
60
  it "initializes without specifying an index" do
36
61
  dv = Daru::Vector.new [1,2,3,4,5], name: :vishnu, dtype: dtype
37
62
 
@@ -39,48 +64,184 @@ describe Daru::Vector do
39
64
  end
40
65
 
41
66
  it "inserts nils for extra indices" do
42
- dv = Daru::Vector.new [1,2,3], name: :yoga, index: [0,1,2,3,4], dtype: Array
67
+ dv = Daru::Vector.new [1,2,3], name: :yoga, index: [0,1,2,3,4], dtype: :array
43
68
 
44
69
  expect(dv).to eq([1,2,3,nil,nil].dv(:yoga,nil, Array))
45
70
  end
46
- end
47
-
48
- context "#[]" do
49
- before :each do
50
- @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga,
51
- index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
52
- end
53
71
 
54
- it "returns an element after passing an index" do
55
- expect(@dv[:yoda]).to eq(1)
72
+ it "inserts nils for extra indices (MultiIndex)" do
73
+ dv = Daru::Vector.new [1,2], name: :mi, index: @multi_index, dtype: :array
74
+ expect(dv).to eq(Daru::Vector.new([1,2,nil,nil], name: :mi, index: @multi_index, dtype: :array))
56
75
  end
76
+ end
57
77
 
58
- it "returns an element after passing a numeric index" , :focus => true do
59
- expect(@dv[0]).to eq(1)
78
+ context "#[]" do
79
+ context Daru::Index do
80
+ before :each do
81
+ @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga,
82
+ index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
83
+ end
84
+
85
+ it "returns an element after passing an index" do
86
+ expect(@dv[:yoda]).to eq(1)
87
+ end
88
+
89
+ it "returns an element after passing a numeric index" do
90
+ expect(@dv[0]).to eq(1)
91
+ end
92
+
93
+ it "returns a vector with given indices for multiple indices" do
94
+ expect(@dv[:yoda, :anakin]).to eq(Daru::Vector.new([1,2], name: :yoda,
95
+ index: [:yoda, :anakin], dtype: dtype))
96
+ end
97
+
98
+ it "returns a vector with given indices for multiple numeric indices" do
99
+ expect(@dv[0,1]).to eq(Daru::Vector.new([1,2], name: :yoda,
100
+ index: [:yoda, :anakin], dtype: dtype))
101
+ end
102
+
103
+ it "returns a vector when specified symbol Range" do
104
+ expect(@dv[:yoda..:anakin]).to eq(Daru::Vector.new([1,2],
105
+ index: [:yoda, :anakin], name: :yoga, dtype: dtype))
106
+ end
107
+
108
+ it "returns a vector when specified numeric Range" do
109
+ expect(@dv[3..4]).to eq(Daru::Vector.new([4,5], name: :yoga,
110
+ index: [:padme, :r2d2], name: :yoga, dtype: dtype))
111
+ end
60
112
  end
61
113
 
62
- it "returns a vector with given indices for multiple indices" do
63
- expect(@dv[:yoda, :anakin]).to eq(Daru::Vector.new([1,2], name: :yoda,
64
- index: [:yoda, :anakin], dtype: dtype))
114
+ context Daru::MultiIndex do
115
+ before do
116
+ @tuples = [
117
+ [:a,:one,:bar],
118
+ [:a,:one,:baz],
119
+ [:a,:two,:bar],
120
+ [:a,:two,:baz],
121
+ [:b,:one,:bar],
122
+ [:b,:two,:bar],
123
+ [:b,:two,:baz],
124
+ [:b,:one,:foo],
125
+ [:c,:one,:bar],
126
+ [:c,:one,:baz],
127
+ [:c,:two,:foo],
128
+ [:c,:two,:bar]
129
+ ]
130
+ @multi_index = Daru::MultiIndex.new(@tuples)
131
+ @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index,
132
+ dtype: dtype, name: :mi_vector
133
+ end
134
+
135
+ it "returns a single element when passed a row number" do
136
+ expect(@vector[1]).to eq(1)
137
+ end
138
+
139
+ it "returns a single element when passed the full tuple" do
140
+ expect(@vector[:a, :one, :baz]).to eq(1)
141
+ end
142
+
143
+ it "returns sub vector when passed first layer of tuple" do
144
+ mi = Daru::MultiIndex.new([
145
+ [:one,:bar],
146
+ [:one,:baz],
147
+ [:two,:bar],
148
+ [:two,:baz]])
149
+ expect(@vector[:a]).to eq(Daru::Vector.new([0,1,2,3], index: mi,
150
+ dtype: dtype, name: :sub_vector))
151
+ end
152
+
153
+ it "returns sub vector when passed first and second layer of tuple" do
154
+ mi = Daru::MultiIndex.new([
155
+ [:foo],
156
+ [:bar]])
157
+ expect(@vector[:c,:two]).to eq(Daru::Vector.new([10,11], index: mi,
158
+ dtype: dtype, name: :sub_sub_vector))
159
+ end
160
+
161
+ it "returns a vector with corresponding MultiIndex when specified numeric Range" do
162
+ mi = Daru::MultiIndex.new([
163
+ [:a,:two,:baz],
164
+ [:b,:one,:bar],
165
+ [:b,:two,:bar],
166
+ [:b,:two,:baz],
167
+ [:b,:one,:foo],
168
+ [:c,:one,:bar],
169
+ [:c,:one,:baz]
170
+ ])
171
+ expect(@vector[3..9]).to eq(Daru::Vector.new([3,4,5,6,7,8,9], index: mi,
172
+ dtype: dtype, name: :slice))
173
+ end
65
174
  end
66
175
  end
67
176
 
68
177
  context "#[]=" do
69
- before :each do
70
- @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga,
71
- index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
178
+ context Daru::Index do
179
+ before :each do
180
+ @dv = Daru::Vector.new [1,2,3,4,5], name: :yoga,
181
+ index: [:yoda, :anakin, :obi, :padme, :r2d2], dtype: dtype
182
+ end
183
+
184
+ it "assigns at the specified index" do
185
+ @dv[:yoda] = 666
186
+ expect(@dv[:yoda]).to eq(666)
187
+ end
188
+
189
+ it "assigns at the specified Integer index" do
190
+ @dv[0] = 666
191
+ expect(@dv[:yoda]).to eq(666)
192
+ end
193
+
194
+ it "sets dtype to Array if a nil is assigned" do
195
+ @dv[0] = nil
196
+ expect(@dv.dtype).to eq(:array)
197
+ end
72
198
  end
73
199
 
74
- it "assigns at the specified index" do
75
- @dv[:yoda] = 666
76
-
77
- expect(@dv[:yoda]).to eq(666)
78
- end
79
-
80
- it "assigns at the specified Integer index" do
81
- @dv[0] = 666
82
-
83
- expect(@dv[:yoda]).to eq(666)
200
+ context Daru::MultiIndex do
201
+ before :each do
202
+ @tuples = [
203
+ [:a,:one,:bar],
204
+ [:a,:one,:baz],
205
+ [:a,:two,:bar],
206
+ [:a,:two,:baz],
207
+ [:b,:one,:bar],
208
+ [:b,:two,:bar],
209
+ [:b,:two,:baz],
210
+ [:b,:one,:foo],
211
+ [:c,:one,:bar],
212
+ [:c,:one,:baz],
213
+ [:c,:two,:foo],
214
+ [:c,:two,:bar]
215
+ ]
216
+ @multi_index = Daru::MultiIndex.new(@tuples)
217
+ @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index,
218
+ dtype: dtype, name: :mi_vector
219
+ end
220
+
221
+ it "assigns all lower layer indices when specified a first layer index" do
222
+ @vector[:b] = 69
223
+ expect(@vector).to eq(Daru::Vector.new([0,1,2,3,69,69,69,69,8,9,10,11],
224
+ index: @multi_index, name: :top_layer_assignment, dtype: dtype
225
+ ))
226
+ end
227
+
228
+ it "assigns all lower indices when specified first and second layer index" do
229
+ @vector[:b, :one] = 69
230
+ expect(@vector).to eq(Daru::Vector.new([0,1,2,3,69,5,6,69,8,9,10,11],
231
+ index: @multi_index, name: :second_layer_assignment, dtype: dtype))
232
+ end
233
+
234
+ it "assigns just the precise value when specified complete tuple" do
235
+ @vector[:b, :one, :foo] = 69
236
+ expect(@vector).to eq(Daru::Vector.new([0,1,2,3,4,5,6,69,8,9,10,11],
237
+ index: @multi_index, name: :precise_assignment, dtype: dtype))
238
+ end
239
+
240
+ it "assigns correctly when numeric index" do
241
+ @vector[7] = 69
242
+ expect(@vector).to eq(Daru::Vector.new([0,1,2,3,4,5,6,69,8,9,10,11],
243
+ index: @multi_index, name: :precise_assignment, dtype: dtype))
244
+ end
84
245
  end
85
246
  end
86
247
 
@@ -116,57 +277,344 @@ describe Daru::Vector do
116
277
  end
117
278
 
118
279
  context "#delete" do
119
- it "deletes specified value in the vector" do
120
- dv = Daru::Vector.new [1,2,3,4,5], name: :a, dtype: dtype
280
+ context Daru::Index do
281
+ it "deletes specified value in the vector" do
282
+ dv = Daru::Vector.new [1,2,3,4,5], name: :a, dtype: dtype
121
283
 
122
- dv.delete 3
284
+ dv.delete 3
285
+ expect(dv).to eq(Daru::Vector.new [1,2,4,5], name: :a)
286
+ end
287
+ end
123
288
 
124
- expect(dv).to eq(Daru::Vector.new [1,2,4,5], name: :a)
289
+ context Daru::MultiIndex do
290
+ pending
125
291
  end
126
292
  end
127
293
 
128
294
  context "#delete_at" do
129
- before :each do
130
- @dv = Daru::Vector.new [1,2,3,4,5], name: :a,
131
- index: [:one, :two, :three, :four, :five], dtype: dtype
132
- end
295
+ context Daru::Index do
296
+ before :each do
297
+ @dv = Daru::Vector.new [1,2,3,4,5], name: :a,
298
+ index: [:one, :two, :three, :four, :five], dtype: dtype
299
+ end
133
300
 
134
- it "deletes element of specified index" do
135
- @dv.delete_at :one
301
+ it "deletes element of specified index" do
302
+ @dv.delete_at :one
136
303
 
137
- expect(@dv).to eq(Daru::Vector.new [2,3,4,5], name: :a,
138
- index: [:two, :three, :four, :five]), dtype: dtype
139
- end
304
+ expect(@dv).to eq(Daru::Vector.new [2,3,4,5], name: :a,
305
+ index: [:two, :three, :four, :five]), dtype: dtype
306
+ end
307
+
308
+ it "deletes element of specified integer index" do
309
+ @dv.delete_at 2
140
310
 
141
- it "deletes element of specified integer index" do
142
- @dv.delete_at 2
311
+ expect(@dv).to eq(Daru::Vector.new [1,2,4,5], name: :a,
312
+ index: [:one, :two, :four, :five]), dtype: dtype
313
+ end
314
+ end
143
315
 
144
- expect(@dv).to eq(Daru::Vector.new [1,2,4,5], name: :a,
145
- index: [:one, :two, :four, :five]), dtype: dtype
316
+ context Daru::MultiIndex do
317
+ pending "Possibly next release"
146
318
  end
147
319
  end
148
320
 
149
321
  context "#index_of" do
150
- it "returns index of specified value" do
151
- dv = Daru::Vector.new [1,2,3,4,5], name: :a,
152
- index: [:one, :two, :three, :four, :five], dtype: dtype
322
+ context Daru::Index do
323
+ it "returns index of specified value" do
324
+ dv = Daru::Vector.new [1,2,3,4,5], name: :a,
325
+ index: [:one, :two, :three, :four, :five], dtype: dtype
153
326
 
154
- expect(dv.index_of(1)).to eq(:one)
327
+ expect(dv.index_of(1)).to eq(:one)
328
+ end
329
+ end
330
+
331
+ context Daru::MultiIndex do
332
+ it "returns tuple of specified value" do
333
+ mi = Daru::MultiIndex.new([
334
+ [:a,:two,:bar],
335
+ [:a,:two,:baz],
336
+ [:b,:one,:bar],
337
+ [:b,:two,:bar]
338
+ ])
339
+ vector = Daru::Vector.new([1,2,3,4], index: mi, dtype: dtype)
340
+ expect(vector.index_of(3)).to eq([:b,:one,:bar])
341
+ end
155
342
  end
156
343
  end
157
344
 
158
345
  context "#to_hash" do
159
- it "returns the vector as a hash" do
160
- dv = Daru::Vector.new [1,2,3,4,5], name: :a,
161
- index: [:one, :two, :three, :four, :five], dtype: dtype
346
+ context Daru::Index do
347
+ it "returns the vector as a hash" do
348
+ dv = Daru::Vector.new [1,2,3,4,5], name: :a,
349
+ index: [:one, :two, :three, :four, :five], dtype: dtype
350
+
351
+ expect(dv.to_hash).to eq({one: 1, two: 2, three: 3, four: 4, five: 5})
352
+ end
353
+ end
162
354
 
163
- expect(dv.to_hash).to eq({one: 1, two: 2, three: 3, four: 4, five: 5})
355
+ context Daru::MultiIndex do
356
+ pending
357
+ # it "returns vector as a Hash" do
358
+ # pending
359
+ # mi = Daru::MultiIndex.new([
360
+ # [:a,:two,:bar],
361
+ # [:a,:two,:baz],
362
+ # [:b,:one,:bar],
363
+ # [:b,:two,:bar]
364
+ # ])
365
+ # vector = Daru::Vector.new([1,2,3,4], index: mi, dtype: dtype)
366
+ # expect(vector.to_hash).to eq({
367
+ # [:a,:two,:bar] => 1,
368
+ # [:a,:two,:baz] => 2,
369
+ # [:b,:one,:bar] => 3,
370
+ # [:b,:two,:bar] => 4
371
+ # })
372
+ # end
164
373
  end
165
374
  end
166
375
 
167
376
  context "#uniq" do
168
- # TODO
377
+ it "keeps only unique values" do
378
+ # TODO: fill this in
379
+ end
380
+ end
381
+
382
+ context "#cast" do
383
+ ALL_DTYPES.each do |new_dtype|
384
+ it "casts from #{dtype} to #{new_dtype}" do
385
+ v = Daru::Vector.new [1,2,3,4], dtype: dtype
386
+ v.cast(dtype: new_dtype)
387
+ expect(v.dtype).to eq(new_dtype)
388
+ end
389
+ end
169
390
  end
391
+
392
+ context "#sort" do
393
+ context Daru::Index do
394
+ before do
395
+ @dv = Daru::Vector.new [33,2,15,332,1], name: :dv, index: [:a, :b, :c, :d, :e]
396
+ end
397
+
398
+ it "sorts the vector with defaults and returns a new vector, preserving indexing" do
399
+ expect(@dv.sort).to eq(Daru::Vector.new([1,2,15,33,332], name: :dv, index: [:e, :b, :c, :a, :d]))
400
+ end
401
+
402
+ it "sorts the vector in descending order" do
403
+ expect(@dv.sort(ascending: false)).to eq(Daru::Vector.new([332,33,15,2,1], name: :dv, index: [:d, :a, :c, :b, :e]))
404
+ end
405
+
406
+ it "accepts a block" do
407
+ str_dv = Daru::Vector.new ["My Jazz Guitar", "Jazz", "My", "Guitar"]
408
+
409
+ sorted = str_dv.sort { |a,b| a.length <=> b.length }
410
+ expect(sorted).to eq(Daru::Vector.new(["My", "Jazz", "Guitar", "My Jazz Guitar"], index: [2,1,3,0]))
411
+ end
412
+
413
+ it "places nils near the end of the vector" do
414
+ pending
415
+ with_nils = Daru::Vector.new [22,4,nil,111,nil,2]
416
+
417
+ expect(with_nils.sort).to eq(Daru::Vector.new([2,4,22,111,nil,nil], index: [5,1,0,3,2,4]))
418
+ end if dtype == :array
419
+ end
420
+
421
+ context Daru::MultiIndex do
422
+ before do
423
+ mi = Daru::MultiIndex.new([
424
+ [:a, :one, :foo],
425
+ [:a, :two, :bar],
426
+ [:b, :one, :bar],
427
+ [:b, :two, :baz],
428
+ [:b, :three, :bar]
429
+ ])
430
+ @vector = Daru::Vector.new([44,22,111,0,-56], index: mi, name: :unsorted,
431
+ dtype: dtype)
432
+ end
433
+
434
+ it "sorts vector" do
435
+ mi_asc = Daru::MultiIndex.new([
436
+ [:b, :three, :bar],
437
+ [:b, :two, :baz],
438
+ [:a, :two, :bar],
439
+ [:a, :one, :foo],
440
+ [:b, :one, :bar]
441
+ ])
442
+ expect(@vector.sort).to eq(Daru::Vector.new([-56,0,22,44,111], index: mi_asc,
443
+ name: :ascending, dtype: dtype))
444
+ end
445
+
446
+ it "sorts in descending" do
447
+ mi_dsc = Daru::MultiIndex.new([
448
+ [:b, :one, :bar],
449
+ [:a, :one, :foo],
450
+ [:a, :two, :bar],
451
+ [:b, :two, :baz],
452
+ [:b, :three, :bar]
453
+ ])
454
+ expect(@vector.sort(ascending: false)).to eq(Daru::Vector.new(
455
+ [111,44,22,0,-56], index: mi_dsc, name: :descending, dtype: dtype))
456
+ end
457
+
458
+ it "sorts using the supplied block" do
459
+ mi_abs = Daru::MultiIndex.new([
460
+ [:b, :two, :baz],
461
+ [:a, :two, :bar],
462
+ [:a, :one, :foo],
463
+ [:b, :three, :bar],
464
+ [:b, :one, :bar]
465
+ ])
466
+ expect(@vector.sort { |a,b| a.abs <=> b.abs }).to eq(Daru::Vector.new(
467
+ [0,22,44,-56,111], index: mi_abs, name: :sort_abs, dtype: dtype))
468
+ end
469
+ end
470
+ end
471
+
472
+ context "#reindex" do
473
+ context Daru::Index do
474
+ before do
475
+ @dv = Daru::Vector.new [1,2,3,4,5], name: :dv, index: [:a, :b, :c, :d, :e]
476
+ end
477
+
478
+ it "recreates index with sequential numbers" do
479
+ a = @dv.reindex(:seq)
480
+
481
+ expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [0,1,2,3,4]))
482
+ expect(a).to_not eq(@dv)
483
+ end
484
+
485
+ it "accepts a new non-numeric index" do
486
+ a = @dv.reindex([:hello, :my, :name, :is, :ted])
487
+
488
+ expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [:hello, :my, :name, :is, :ted]))
489
+ expect(a).to_not eq(@dv)
490
+ end
491
+ end
492
+
493
+ context Daru::MultiIndex do
494
+ pending
495
+ end
496
+ end
497
+ end
498
+ end # checking with ALL_DTYPES
499
+
500
+ # works with arrays only
501
+ context "#is_nil?" do
502
+ before(:each) do
503
+ @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
504
+ @without_md = Daru::Vector.new([1,2,3,4,5,6])
505
+ end
506
+
507
+ it "verifies missing data presence" do
508
+ expect(@with_md.is_nil?) .to eq(Daru::Vector.new([false,false,true,false,false,true]))
509
+ expect(@without_md.is_nil?).to eq(Daru::Vector.new([false,false,false,false,false,false]))
510
+ end
511
+ end
512
+
513
+ context "#clone_structure" do
514
+ context Daru::Index do
515
+ it "clones a vector with its index and fills it with nils" do
516
+ vec = Daru::Vector.new([1,2,3,4,5], index: [:a,:b,:c,:d,:e])
517
+ expect(vec.clone_structure).to eq(Daru::Vector.new([nil,nil,nil,nil,nil], index: [:a,:b,:c,:d,:e]))
518
+ end
519
+ end
520
+
521
+ context Daru::MultiIndex do
522
+ pending
523
+ end
524
+ end
525
+
526
+ context "#nil_positions" do
527
+ context Daru::Index do
528
+ before(:each) do
529
+ @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
530
+ end
531
+
532
+ it "returns the indexes of nils" do
533
+ expect(@with_md.nil_positions).to eq([2,5])
534
+ end
535
+
536
+ it "updates after assingment" do
537
+ @with_md[3] = nil
538
+ expect(@with_md.nil_positions).to eq([2,3,5])
539
+ end
540
+ end
541
+
542
+ context Daru::MultiIndex do
543
+ pending
544
+ end
545
+ end
546
+
547
+ context "#replace_nils" do
548
+ it "replaces all nils with the specified value" do
549
+ vec = Daru::Vector.new([1,2,3,nil,nil,4])
550
+ expect(vec.replace_nils(2)).to eq(Daru::Vector.new([1,2,3,2,2,4]))
551
+ end
552
+
553
+ it "replaces all nils with the specified value (bang)" do
554
+ vec = Daru::Vector.new([1,2,3,nil,nil,4]).replace_nils!(2)
555
+ expect(vec).to eq(Daru::Vector.new([1,2,3,2,2,4]))
556
+ end
557
+ end
558
+
559
+ context "#type" do
560
+ before(:each) do
561
+ @numeric = Daru::Vector.new([1,2,3,4,5])
562
+ @multi = Daru::Vector.new([1,2,3,'sameer','d'])
563
+ @with_nils = Daru::Vector.new([1,2,3,4,nil])
564
+ end
565
+
566
+ it "checks numeric data correctly" do
567
+ expect(@numeric.type).to eq(:numeric)
568
+ end
569
+
570
+ it "checks for multiple types of data" do
571
+ expect(@multi.type).to eq(:object)
572
+ end
573
+
574
+ it "tells NMatrix data type in case of NMatrix wrapper" do
575
+ nm = Daru::Vector.new([1,2,3,4,5], dtype: :nmatrix)
576
+ expect(nm.type).to eq(:int32)
577
+ end
578
+
579
+ it "changes type to object as per assignment" do
580
+ expect(@numeric.type).to eq(:numeric)
581
+ @numeric[2] = 'my string'
582
+ expect(@numeric.type).to eq(:object)
583
+ end
584
+
585
+ it "changes type to numeric as per assignment" do
586
+ expect(@multi.type).to eq(:object)
587
+ @multi[3] = 45
588
+ @multi[4] = 54
589
+ expect(@multi.type).to eq(:numeric)
590
+ end
591
+
592
+ it "reports numeric if nils with number data" do
593
+ expect(@with_nils.type).to eq(:numeric)
594
+ end
595
+
596
+ it "stays numeric when nil is reassigned to a number" do
597
+ @with_nils[4] = 66
598
+ expect(@with_nils.type).to eq(:numeric)
599
+ end
600
+
601
+ it "changes to :object when nil is reassigned to anything but a number" do
602
+ @with_nils[4] = 'string'
603
+ expect(@with_nils.type).to eq(:object)
604
+ end
605
+ end
606
+
607
+ context "#to_matrix" do
608
+ before do
609
+ @vector = Daru::Vector.new [1,2,3,4,5,6]
610
+ end
611
+
612
+ it "converts Daru::Vector to a horizontal Ruby Matrix" do
613
+ expect(@vector.to_matrix).to eq(Matrix[[1,2,3,4,5,6]])
614
+ end
615
+
616
+ it "converts Daru::Vector to a vertical Ruby Matrix" do
617
+ expect(@vector.to_matrix(:vertical)).to eq(Matrix.columns([[1,2,3,4,5,6]]))
170
618
  end
171
619
  end
172
- end if mri?
620
+ end if mri?