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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +0 -0
- data/Gemfile +0 -1
- data/History.txt +35 -0
- data/README.md +178 -198
- data/daru.gemspec +5 -7
- data/lib/daru.rb +10 -2
- data/lib/daru/accessors/array_wrapper.rb +36 -198
- data/lib/daru/accessors/nmatrix_wrapper.rb +60 -209
- data/lib/daru/core/group_by.rb +183 -0
- data/lib/daru/dataframe.rb +615 -167
- data/lib/daru/index.rb +17 -16
- data/lib/daru/io/io.rb +5 -12
- data/lib/daru/maths/arithmetic/dataframe.rb +72 -8
- data/lib/daru/maths/arithmetic/vector.rb +19 -6
- data/lib/daru/maths/statistics/dataframe.rb +103 -2
- data/lib/daru/maths/statistics/vector.rb +102 -61
- data/lib/daru/monkeys.rb +8 -0
- data/lib/daru/multi_index.rb +199 -0
- data/lib/daru/plotting/dataframe.rb +24 -24
- data/lib/daru/plotting/vector.rb +14 -15
- data/lib/daru/vector.rb +402 -98
- data/lib/version.rb +1 -1
- data/notebooks/grouping_splitting_pivots.ipynb +529 -0
- data/notebooks/intro_with_music_data_.ipynb +104 -119
- data/spec/accessors/wrappers_spec.rb +36 -0
- data/spec/core/group_by_spec.rb +331 -0
- data/spec/dataframe_spec.rb +1237 -475
- data/spec/fixtures/sales-funnel.csv +18 -0
- data/spec/index_spec.rb +10 -21
- data/spec/io/io_spec.rb +4 -14
- data/spec/math/arithmetic/dataframe_spec.rb +66 -0
- data/spec/math/arithmetic/vector_spec.rb +45 -4
- data/spec/math/statistics/dataframe_spec.rb +91 -1
- data/spec/math/statistics/vector_spec.rb +32 -6
- data/spec/monkeys_spec.rb +10 -1
- data/spec/multi_index_spec.rb +216 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/vector_spec.rb +505 -57
- 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
|
data/spec/spec_helper.rb
CHANGED
data/spec/vector_spec.rb
CHANGED
@@ -1,9 +1,22 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
describe Daru::Vector do
|
4
|
-
[
|
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:
|
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 "
|
55
|
-
|
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
|
-
|
59
|
-
|
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
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
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
|
-
|
120
|
-
|
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
|
-
|
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
|
-
|
289
|
+
context Daru::MultiIndex do
|
290
|
+
pending
|
125
291
|
end
|
126
292
|
end
|
127
293
|
|
128
294
|
context "#delete_at" do
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
-
|
135
|
-
|
301
|
+
it "deletes element of specified index" do
|
302
|
+
@dv.delete_at :one
|
136
303
|
|
137
|
-
|
138
|
-
|
139
|
-
|
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
|
-
|
142
|
-
|
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
|
-
|
145
|
-
|
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
|
-
|
151
|
-
|
152
|
-
|
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
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
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
|
-
|
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?
|