daru 0.0.4 → 0.0.5

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.
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?