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
@@ -1,635 +1,1397 @@
1
1
  require 'spec_helper.rb'
2
2
 
3
3
  describe Daru::DataFrame do
4
- [Array].each do |dtype|
5
- describe dtype do
6
- before :each do
7
- @data_frame = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
8
- c: [11,22,33,44,55]},
9
- order: [:a, :b, :c],
10
- index: [:one, :two, :three, :four, :five], dtype: dtype)
4
+ before :each do
5
+ @data_frame = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
6
+ c: [11,22,33,44,55]},
7
+ order: [:a, :b, :c],
8
+ index: [:one, :two, :three, :four, :five])
9
+ tuples = [
10
+ [:a,:one,:bar],
11
+ [:a,:one,:baz],
12
+ [:a,:two,:bar],
13
+ [:a,:two,:baz],
14
+ [:b,:one,:bar],
15
+ [:b,:two,:bar],
16
+ [:b,:two,:baz],
17
+ [:b,:one,:foo],
18
+ [:c,:one,:bar],
19
+ [:c,:one,:baz],
20
+ [:c,:two,:foo],
21
+ [:c,:two,:bar]
22
+ ]
23
+ @multi_index = Daru::MultiIndex.new(tuples)
24
+
25
+ @vector_arry1 = [11,12,13,14,11,12,13,14,11,12,13,14]
26
+ @vector_arry2 = [1,2,3,4,1,2,3,4,1,2,3,4]
27
+
28
+ @order_mi = Daru::MultiIndex.new([
29
+ [:a,:one,:bar],
30
+ [:a,:two,:baz],
31
+ [:b,:two,:foo],
32
+ [:b,:one,:foo]])
33
+
34
+ @df_mi = Daru::DataFrame.new([
35
+ @vector_arry1,
36
+ @vector_arry2,
37
+ @vector_arry1,
38
+ @vector_arry2], order: @order_mi, index: @multi_index)
39
+ end
40
+
41
+ context ".rows" do
42
+ before do
43
+ @rows = [
44
+ [1,2,3,4,5],
45
+ [1,2,3,4,5],
46
+ [1,2,3,4,5],
47
+ [1,2,3,4,5]
48
+ ]
49
+ end
50
+
51
+ context Daru::Index do
52
+ it "creates a DataFrame from Array rows" do
53
+ df = Daru::DataFrame.rows @rows, order: [:a,:b,:c,:d,:e]
54
+
55
+ expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
56
+ expect(df.vectors) .to eq(Daru::Index.new [:a,:b,:c,:d,:e])
57
+ expect(df.vector[:a]) .to eq(Daru::Vector.new [1,1,1,1])
11
58
  end
12
59
 
13
- context ".rows" do
14
- before do
15
- @rows = [
16
- [1,2,3,4,5],
17
- [1,2,3,4,5],
18
- [1,2,3,4,5],
19
- [1,2,3,4,5]
20
- ]
21
- end
60
+ it "creates a DataFrame from Vector rows" do
61
+ rows = @rows.map { |r| Daru::Vector.new r, index: [:a,:b,:c,:d,:e] }
22
62
 
23
- it "creates a DataFrame from Array rows" do
24
- df = Daru::DataFrame.rows @rows, order: [:a,:b,:c,:d,:e]
63
+ df = Daru::DataFrame.rows rows, order: [:a,:b,:c,:d,:e]
25
64
 
26
- expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
27
- expect(df.vectors) .to eq(Daru::Index.new [:a,:b,:c,:d,:e])
28
- expect(df.vector[:a]) .to eq(Daru::Vector.new [1,1,1,1])
29
- end
65
+ expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
66
+ expect(df.vectors) .to eq(Daru::Index.new [:a,:b,:c,:d,:e])
67
+ expect(df.vector[:a]) .to eq(Daru::Vector.new [1,1,1,1])
68
+ end
69
+ end
30
70
 
31
- it "creates a DataFrame from Vector rows" do
32
- rows = @rows.map { |r| Daru::Vector.new r, index: [:a,:b,:c,:d,:e] }
71
+ context Daru::MultiIndex do
72
+ it "creates a DataFrame from rows" do
73
+ df = Daru::DataFrame.rows(@rows*3, index: @multi_index, order: [:a,:b,:c,:d,:e])
33
74
 
34
- df = Daru::DataFrame.rows rows, order: [:a,:b,:c,:d,:e]
75
+ expect(df.index) .to eq(@multi_index)
76
+ expect(df.vectors) .to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
77
+ expect(df.vector[:a]).to eq(Daru::Vector.new([1]*12, index: @multi_index))
78
+ end
35
79
 
36
- expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
37
- expect(df.vectors) .to eq(Daru::Index.new [:a,:b,:c,:d,:e])
38
- expect(df.vector[:a]) .to eq(Daru::Vector.new [1,1,1,1])
39
- end
80
+ it "crates a DataFrame from rows (MultiIndex order)" do
81
+ rows = [
82
+ [11, 1, 11, 1],
83
+ [12, 2, 12, 2],
84
+ [13, 3, 13, 3],
85
+ [14, 4, 14, 4]
86
+ ]
87
+ index = Daru::MultiIndex.new([
88
+ [:one,:bar],
89
+ [:one,:baz],
90
+ [:two,:foo],
91
+ [:two,:bar]
92
+ ])
93
+
94
+ df = Daru::DataFrame.rows(rows, index: index, order: @order_mi)
95
+ expect(df.index) .to eq(index)
96
+ expect(df.vectors).to eq(@order_mi)
97
+ expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new([11,12,13,14],
98
+ index: index))
40
99
  end
41
100
 
42
- context "#initialize" do
43
- it "initializes an empty DataFrame" do
44
- df = Daru::DataFrame.new({}, order: [:a, :b], dtype: dtype)
101
+ it "creates a DataFrame from Vector rows" do
102
+ rows = @rows*3
103
+ rows.map! { |r| Daru::Vector.new(r, index: @multi_index) }
45
104
 
46
- expect(df.vectors).to eq(Daru::Index.new [:a, :b])
47
- expect(df.a.class).to eq(Daru::Vector)
48
- expect(df.a) .to eq([].dv(:a))
49
- end
105
+ df = Daru::DataFrame.rows rows, order: @multi_index
50
106
 
51
- it "initializes from a Hash" do
52
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]}, order: [:a, :b],
53
- index: [:one, :two, :three, :four, :five], dtype: dtype)
107
+ expect(df.index).to eq(Daru::Index.new(Array.new(rows.size) { |i| i }))
108
+ expect(df.vectors).to eq(@multi_index)
109
+ expect(df.vector[:a,:one,:bar]).to eq(Daru::Vector.new([1]*12))
110
+ end
111
+ end
112
+ end
54
113
 
55
- expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
56
- expect(df.vectors).to eq(Daru::Index.new [:a, :b])
57
- expect(df.a.class).to eq(Daru::Vector)
58
- expect(df.a) .to eq([1,2,3,4,5].dv(:a, df.index))
59
- end
114
+ context "#initialize" do
115
+ context Daru::Index do
116
+ it "initializes an empty DataFrame" do
117
+ df = Daru::DataFrame.new({}, order: [:a, :b])
60
118
 
61
- it "initializes from a Hash of Vectors", :focus => true do
62
- df = Daru::DataFrame.new({b: [11,12,13,14,15].dv(:b, [:one, :two, :three, :four, :five]),
63
- a: [1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five])}, order: [:a, :b],
64
- index: [:one, :two, :three, :four, :five], dtype: dtype)
119
+ expect(df.vectors).to eq(Daru::Index.new [:a, :b])
120
+ expect(df.a.class).to eq(Daru::Vector)
121
+ expect(df.a) .to eq([].dv(:a))
122
+ end
65
123
 
66
- expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
67
- expect(df.vectors).to eq(Daru::Index.new [:a, :b])
68
- expect(df.a.class).to eq(Daru::Vector)
69
- expect(df.a) .to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
70
- end
124
+ it "initializes from a Hash" do
125
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]}, order: [:a, :b],
126
+ index: [:one, :two, :three, :four, :five])
127
+
128
+ expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
129
+ expect(df.vectors).to eq(Daru::Index.new [:a, :b])
130
+ expect(df.a.class).to eq(Daru::Vector)
131
+ expect(df.a) .to eq([1,2,3,4,5].dv(:a, df.index))
132
+ end
71
133
 
72
- it "initializes from an Array of Hashes" do
73
- df = Daru::DataFrame.new([{a: 1, b: 11}, {a: 2, b: 12}, {a: 3, b: 13},
74
- {a: 4, b: 14}, {a: 5, b: 15}], order: [:b, :a],
75
- index: [:one, :two, :three, :four, :five], dtype: dtype)
134
+ it "initializes from a Hash of Vectors" do
135
+ df = Daru::DataFrame.new({b: [11,12,13,14,15].dv(:b, [:one, :two, :three, :four, :five]),
136
+ a: [1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five])}, order: [:a, :b],
137
+ index: [:one, :two, :three, :four, :five])
76
138
 
77
- expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
78
- expect(df.vectors).to eq(Daru::Index.new [:b, :a])
79
- expect(df.a.class).to eq(Daru::Vector)
80
- expect(df.a) .to eq([1,2,3,4,5].dv(:a,[:one, :two, :three, :four, :five]))
81
- end
139
+ expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
140
+ expect(df.vectors).to eq(Daru::Index.new [:a, :b])
141
+ expect(df.a.class).to eq(Daru::Vector)
142
+ expect(df.a) .to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
143
+ end
82
144
 
83
- it "accepts Index objects for row/col" do
84
- rows = Daru::Index.new [:one, :two, :three, :four, :five]
85
- cols = Daru::Index.new [:a, :b]
145
+ it "initializes from an Array of Hashes" do
146
+ df = Daru::DataFrame.new([{a: 1, b: 11}, {a: 2, b: 12}, {a: 3, b: 13},
147
+ {a: 4, b: 14}, {a: 5, b: 15}], order: [:b, :a],
148
+ index: [:one, :two, :three, :four, :five])
86
149
 
87
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]}, order: cols,
88
- index: rows, dtype: dtype)
150
+ expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
151
+ expect(df.vectors).to eq(Daru::Index.new [:b, :a])
152
+ expect(df.a.class).to eq(Daru::Vector)
153
+ expect(df.a) .to eq([1,2,3,4,5].dv(:a,[:one, :two, :three, :four, :five]))
154
+ end
89
155
 
90
- expect(df.a) .to eq(Daru::Vector.new([1,2,3,4,5], order: [:a], index: rows, dtype: dtype))
91
- expect(df.b) .to eq(Daru::Vector.new([11,12,13,14,15], name: :b, index: rows, dtype: dtype))
92
- expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
93
- expect(df.vectors).to eq(Daru::Index.new [:a, :b])
94
- end
156
+ it "initializes from Array of Arrays" do
157
+ df = Daru::DataFrame.new([[1]*5, [2]*5, [3]*5], order: [:b, :a, :c])
95
158
 
96
- it "initializes without specifying row/col index" do
97
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]}, dtype: dtype)
159
+ expect(df.index) .to eq(Daru::Index.new(5))
160
+ expect(df.vectors).to eq(Daru::Index.new([:b, :a, :c]))
161
+ expect(df.a) .to eq(Daru::Vector.new([2]*5))
162
+ end
98
163
 
99
- expect(df.index) .to eq(Daru::Index.new [0,1,2,3,4])
100
- expect(df.vectors).to eq(Daru::Index.new [:a, :b])
101
- end
164
+ it "initializes from Array of Vectors" do
165
+ df = Daru::DataFrame.new([Daru::Vector.new([1]*5), Daru::Vector.new([2]*5),
166
+ Daru::Vector.new([3]*5)], order: [:b, :a, :c])
102
167
 
103
- it "aligns indexes properly" do
104
- df = Daru::DataFrame.new({
105
- b: [11,12,13,14,15].dv(:b, [:two, :one, :four, :five, :three]),
106
- a: [1,2,3,4,5].dv(:a, [:two,:one,:three, :four, :five])
107
- },
108
- order: [:a, :b], dtype: dtype
109
- )
110
-
111
- expect(df).to eq(Daru::DataFrame.new({
112
- b: [14,13,12,15,11].dv(:b, [:five, :four, :one, :three, :two]),
113
- a: [5,4,2,3,1].dv(:a, [:five, :four, :one, :three, :two])
114
- }, order: [:a, :b], dtype: dtype)
115
- )
116
- end
168
+ expect(df.index) .to eq(Daru::Index.new(5))
169
+ expect(df.vectors).to eq(Daru::Index.new([:b, :a, :c]))
170
+ expect(df.a) .to eq(Daru::Vector.new([2]*5))
171
+ end
117
172
 
118
- it "adds nil values for missing indexes and aligns by index" do
119
- df = Daru::DataFrame.new({
120
- b: [11,12,13,14,15].dv(:b, [:two, :one, :four, :five, :three]),
121
- a: [1,2,3] .dv(:a, [:two,:one,:three])
122
- },
123
- order: [:a, :b], dtype: dtype
124
- )
125
-
126
- expect(df).to eq(Daru::DataFrame.new({
127
- b: [14,13,12,15,11].dv(:b, [:five, :four, :one, :three, :two]),
128
- a: [nil,nil,2,3,1].dv(:a, [:five, :four, :one, :three, :two])
129
- },
130
- order: [:a, :b], dtype: dtype)
131
- )
132
- end
173
+ it "accepts Index objects for row/col" do
174
+ rows = Daru::Index.new [:one, :two, :three, :four, :five]
175
+ cols = Daru::Index.new [:a, :b]
176
+
177
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]}, order: cols,
178
+ index: rows)
179
+
180
+ expect(df.a) .to eq(Daru::Vector.new([1,2,3,4,5], order: [:a], index: rows))
181
+ expect(df.b) .to eq(Daru::Vector.new([11,12,13,14,15], name: :b, index: rows))
182
+ expect(df.index) .to eq(Daru::Index.new [:one, :two, :three, :four, :five])
183
+ expect(df.vectors).to eq(Daru::Index.new [:a, :b])
184
+ end
185
+
186
+ it "initializes without specifying row/col index" do
187
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]})
133
188
 
134
- it "adds nils in first vector when other vectors have many extra indexes" do
135
- df = Daru::DataFrame.new({
136
- b: [11] .dv(nil, [:one]),
137
- a: [1,2,3] .dv(nil, [:one, :two, :three]),
138
- c: [11,22,33,44,55] .dv(nil, [:one, :two, :three, :four, :five]),
139
- d: [49,69,89,99,108,44].dv(nil, [:one, :two, :three, :four, :five, :six])
140
- }, order: [:a, :b, :c, :d],
141
- index: [:one, :two, :three, :four, :five, :six], dtype: dtype)
142
-
143
- expect(df).to eq(Daru::DataFrame.new({
144
- b: [11,nil,nil,nil,nil,nil].dv(nil, [:one, :two, :three, :four, :five, :six]),
145
- a: [1,2,3,nil,nil,nil] .dv(nil, [:one, :two, :three, :four, :five, :six]),
146
- c: [11,22,33,44,55,nil] .dv(nil, [:one, :two, :three, :four, :five, :six]),
147
- d: [49,69,89,99,108,44] .dv(nil, [:one, :two, :three, :four, :five, :six])
148
- }, order: [:a, :b, :c, :d],
149
- index: [:one, :two, :three, :four, :five, :six], dtype: dtype)
189
+ expect(df.index) .to eq(Daru::Index.new [0,1,2,3,4])
190
+ expect(df.vectors).to eq(Daru::Index.new [:a, :b])
191
+ end
192
+
193
+ it "aligns indexes properly" do
194
+ df = Daru::DataFrame.new({
195
+ b: [11,12,13,14,15].dv(:b, [:two, :one, :four, :five, :three]),
196
+ a: [1,2,3,4,5].dv(:a, [:two,:one,:three, :four, :five])
197
+ },
198
+ order: [:a, :b]
150
199
  )
151
- end
152
200
 
153
- it "correctly matches the supplied DataFrame index with the individual vector indexes" do
154
- df = Daru::DataFrame.new({
155
- b: [11,12,13] .dv(nil, [:one, :bleh, :blah]),
156
- a: [1,2,3,4,5].dv(nil, [:one, :two, :booh, :baah, :three]),
157
- c: [11,22,33,44,55].dv(nil, [0,1,3,:three, :two])
158
- }, order: [:a, :b, :c], index: [:one, :two, :three], dtype: dtype)
159
-
160
- expect(df).to eq(Daru::DataFrame.new({
161
- b: [11,nil,nil].dv(nil, [:one, :two, :three]),
162
- a: [1,2,5] .dv(nil, [:one, :two, :three]),
163
- c: [nil,55,44] .dv(nil, [:one, :two, :three]),
164
- },
165
- order: [:a, :b, :c], index: [:one, :two, :three], dtype: dtype
166
- )
201
+ expect(df).to eq(Daru::DataFrame.new({
202
+ b: [14,13,12,15,11].dv(:b, [:five, :four, :one, :three, :two]),
203
+ a: [5,4,2,3,1].dv(:a, [:five, :four, :one, :three, :two])
204
+ }, order: [:a, :b])
205
+ )
206
+ end
207
+
208
+ it "adds nil values for missing indexes and aligns by index" do
209
+ df = Daru::DataFrame.new({
210
+ b: [11,12,13,14,15].dv(:b, [:two, :one, :four, :five, :three]),
211
+ a: [1,2,3] .dv(:a, [:two,:one,:three])
212
+ },
213
+ order: [:a, :b]
214
+ )
215
+
216
+ expect(df).to eq(Daru::DataFrame.new({
217
+ b: [14,13,12,15,11].dv(:b, [:five, :four, :one, :three, :two]),
218
+ a: [nil,nil,2,3,1].dv(:a, [:five, :four, :one, :three, :two])
219
+ },
220
+ order: [:a, :b])
221
+ )
222
+ end
223
+
224
+ it "adds nils in first vector when other vectors have many extra indexes" do
225
+ df = Daru::DataFrame.new({
226
+ b: [11] .dv(nil, [:one]),
227
+ a: [1,2,3] .dv(nil, [:one, :two, :three]),
228
+ c: [11,22,33,44,55] .dv(nil, [:one, :two, :three, :four, :five]),
229
+ d: [49,69,89,99,108,44].dv(nil, [:one, :two, :three, :four, :five, :six])
230
+ }, order: [:a, :b, :c, :d],
231
+ index: [:one, :two, :three, :four, :five, :six])
232
+
233
+ expect(df).to eq(Daru::DataFrame.new({
234
+ b: [11,nil,nil,nil,nil,nil].dv(nil, [:one, :two, :three, :four, :five, :six]),
235
+ a: [1,2,3,nil,nil,nil] .dv(nil, [:one, :two, :three, :four, :five, :six]),
236
+ c: [11,22,33,44,55,nil] .dv(nil, [:one, :two, :three, :four, :five, :six]),
237
+ d: [49,69,89,99,108,44] .dv(nil, [:one, :two, :three, :four, :five, :six])
238
+ }, order: [:a, :b, :c, :d],
239
+ index: [:one, :two, :three, :four, :five, :six])
240
+ )
241
+ end
242
+
243
+ it "correctly matches the supplied DataFrame index with the individual vector indexes" do
244
+ df = Daru::DataFrame.new({
245
+ b: [11,12,13] .dv(nil, [:one, :bleh, :blah]),
246
+ a: [1,2,3,4,5].dv(nil, [:one, :two, :booh, :baah, :three]),
247
+ c: [11,22,33,44,55].dv(nil, [0,1,3,:three, :two])
248
+ }, order: [:a, :b, :c], index: [:one, :two, :three])
249
+
250
+ expect(df).to eq(Daru::DataFrame.new({
251
+ b: [11,nil,nil].dv(nil, [:one, :two, :three]),
252
+ a: [1,2,5] .dv(nil, [:one, :two, :three]),
253
+ c: [nil,55,44] .dv(nil, [:one, :two, :three]),
254
+ },
255
+ order: [:a, :b, :c], index: [:one, :two, :three]
167
256
  )
168
- end
257
+ )
258
+ end
259
+
260
+ it "completes incomplete vectors" do
261
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
262
+ c: [11,22,33,44,55]}, order: [:a, :c])
169
263
 
170
- it "completes incomplete vectors" do
264
+ expect(df.vectors).to eq([:a,:c,:b].to_index)
265
+ end
266
+
267
+ it "raises error for incomplete DataFrame index" do
268
+ expect {
171
269
  df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
172
- c: [11,22,33,44,55]}, order: [:a, :c], dtype: dtype)
270
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
271
+ index: [:one, :two, :three])
272
+ }.to raise_error
273
+ end
173
274
 
174
- expect(df.vectors).to eq([:a,:c,:b].to_index)
175
- end
275
+ it "raises error for unequal sized vectors/arrays" do
276
+ expect {
277
+ df = Daru::DataFrame.new({b: [11,12,13], a: [1,2,3,4,5],
278
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
279
+ index: [:one, :two, :three])
280
+ }.to raise_error
281
+ end
282
+ end
283
+
284
+ context Daru::MultiIndex do
285
+ it "creates empty DataFrame" do
286
+ df = Daru::DataFrame.new({}, order: @order_mi)
176
287
 
177
- it "raises error for incomplete DataFrame index" do
178
- expect {
179
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
180
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
181
- index: [:one, :two, :three], dtype: dtype)
182
- }.to raise_error
183
- end
288
+ expect(df.vectors).to eq(@order_mi)
289
+ expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new([]))
290
+ end
184
291
 
185
- it "raises error for unequal sized vectors/arrays" do
186
- expect {
187
- df = Daru::DataFrame.new({b: [11,12,13], a: [1,2,3,4,5],
188
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
189
- index: [:one, :two, :three], dtype: dtype)
190
- }.to raise_error
191
- end
292
+ it "creates from Hash" do
293
+ df = Daru::DataFrame.new({
294
+ [:a,:one,:bar] => @vector_arry1,
295
+ [:a,:two,:baz] => @vector_arry2,
296
+ [:b,:one,:foo] => @vector_arry1,
297
+ [:b,:two,:foo] => @vector_arry2
298
+ }, order: @order_mi, index: @multi_index)
299
+
300
+ expect(df.index) .to eq(@multi_index)
301
+ expect(df.vectors) .to eq(@order_mi)
302
+ expect(df.vector[:a,:one,:bar]).to eq(Daru::Vector.new(@vector_arry1,
303
+ index: @multi_index))
192
304
  end
193
305
 
194
- context "#[:vector]" do
195
- before :each do
196
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
197
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
198
- index: [:one, :two, :three, :four, :five], dtype: dtype)
199
- end
306
+ it "creates from Array of Hashes" do
307
+ # TODO
308
+ end
200
309
 
201
- it "returns a Vector" do
202
- expect(@df[:a, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
203
- end
310
+ it "creates from Array of Arrays" do
311
+ df = Daru::DataFrame.new([@vector_arry1, @vector_arry2, @vector_arry1,
312
+ @vector_arry2], index: @multi_index, order: @order_mi)
204
313
 
205
- it "returns a DataFrame" do
206
- temp = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
207
- order: [:a, :b], index: [:one, :two, :three, :four, :five], dtype: dtype)
314
+ expect(df.index) .to eq(@multi_index)
315
+ expect(df.vectors).to eq(@order_mi)
316
+ expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new(@vector_arry1,
317
+ index: @multi_index))
318
+ end
208
319
 
209
- expect(@df[:a, :b, :vector]).to eq(temp)
210
- end
320
+ it "raises error for order MultiIndex of different size than supplied Array" do
321
+ expect {
322
+ df = Daru::DataFrame.new([@vector_arry1, @vector_arry2], order: @order_mi,
323
+ index: @multi_index)
324
+ }.to raise_error
325
+ end
211
326
 
212
- it "accesses vector with Integer index" do
213
- expect(@df[0, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
214
- end
327
+ it "aligns MultiIndexes properly" do
328
+ pending
329
+ mi_a = @order_mi
330
+ mi_b = Daru::MultiIndex.new([
331
+ [:b,:one,:foo],
332
+ [:a,:one,:bar],
333
+ [:b,:two,:foo],
334
+ [:a,:one,:baz]
335
+ ])
336
+ mi_sorted = Daru::MultiIndex.new([
337
+ [:a, :one, :bar],
338
+ [:a, :one, :baz],
339
+ [:b, :one, :foo],
340
+ [:b, :two, :foo]
341
+ ])
342
+ order = Daru::MultiIndex.new([
343
+ [:pee, :que],
344
+ [:pee, :poo]
345
+ ])
346
+ a = Daru::Vector.new([1,2,3,4], index: mi_a)
347
+ b = Daru::Vector.new([11,12,13,14], index: mi_b)
348
+ df = Daru::DataFrame.new([b,a], order: order)
349
+
350
+ expect(df).to eq(Daru::DataFrame.new({
351
+ [:pee, :que] => Daru::Vector.new([1,2,4,3], index: mi_sorted),
352
+ [:pee, :poo] => Daru::Vector.new([12,14,11,13], index: mi_sorted)
353
+ }, order: order_mi))
215
354
  end
216
355
 
217
- context "#[:row]" do
218
- before :each do
219
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
220
- c: [11,22,33,44,55]},
221
- order: [:a, :b, :c],
222
- index: [:one, :two, :three, :four, :five], dtype: dtype)
223
- end
356
+ it "adds nils in case of missing values" do
357
+ # TODO
358
+ end
224
359
 
225
- it "returns a row with the given index" do
226
- expect(@df[:one, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
227
- end
360
+ it "matches individual vector indexing with supplied DataFrame index" do
361
+ # TODO
362
+ end
363
+ end
364
+ end
228
365
 
229
- it "returns a row with given Integer index" do
230
- expect(@df[0, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
231
- end
366
+ context "#[:vector]" do
367
+ context Daru::Index do
368
+ before :each do
369
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
370
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
371
+ index: [:one, :two, :three, :four, :five])
372
+ end
232
373
 
233
- it "returns a row with given Integer index for default index-less DataFrame" do
234
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
235
- c: [11,22,33,44,55]}, order: [:a, :b, :c], dtype: dtype)
374
+ it "returns a Vector" do
375
+ expect(@df[:a, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
376
+ end
236
377
 
237
- expect(df[0, :row]).to eq([1,11,11].dv(nil, [:a, :b, :c]))
238
- end
378
+ it "returns a Vector by default" do
379
+ expect(@df[:a]).to eq(Daru::Vector.new([1,2,3,4,5], name: :a,
380
+ index: [:one, :two, :three, :four, :five]))
239
381
  end
240
382
 
241
- context "#[:vector]=" do
242
- before :each do
243
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
244
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
245
- index: [:one, :two, :three, :four, :five], dtype: dtype)
246
- end
383
+ it "returns a DataFrame" do
384
+ temp = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
385
+ order: [:a, :b], index: [:one, :two, :three, :four, :five])
247
386
 
248
- it "appends an Array as a Daru::Vector" do
249
- @df[:d, :vector] = [69,99,108,85,49]
387
+ expect(@df[:a, :b, :vector]).to eq(temp)
388
+ end
250
389
 
251
- expect(@df.d.class).to eq(Daru::Vector)
252
- end
390
+ it "accesses vector with Integer index" do
391
+ expect(@df[0, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
392
+ end
393
+ end
253
394
 
254
- it "replaces an already present vector" do
255
- @df[:a, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
395
+ context Daru::MultiIndex do
396
+ # See #vector
397
+ end
398
+ end
256
399
 
257
- expect(@df.a).to eq([69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five]))
258
- end
400
+ context "#[:row]" do
401
+ context Daru::Index do
402
+ before :each do
403
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
404
+ c: [11,22,33,44,55]},
405
+ order: [:a, :b, :c],
406
+ index: [:one, :two, :three, :four, :five])
407
+ end
259
408
 
260
- it "appends a new vector to the DataFrame" do
261
- @df[:woo, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
409
+ it "returns a row with the given index" do
410
+ expect(@df[:one, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
411
+ end
262
412
 
263
- expect(@df.vectors).to eq([:a, :b, :c, :woo].to_index)
264
- end
413
+ it "returns a row with given Integer index" do
414
+ expect(@df[0, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
415
+ end
265
416
 
266
- it "creates an index for the new vector if not specified" do
267
- @df[:woo, :vector] = [69,99,108,85,49]
417
+ it "returns a row with given Integer index for default index-less DataFrame" do
418
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
419
+ c: [11,22,33,44,55]}, order: [:a, :b, :c])
268
420
 
269
- expect(@df.woo.index).to eq([:one, :two, :three, :four, :five].to_index)
270
- end
421
+ expect(df[0, :row]).to eq([1,11,11].dv(nil, [:a, :b, :c]))
422
+ end
423
+ end
271
424
 
272
- it "matches index of vector to be inserted with the DataFrame index" do
273
- @df[:shankar, :vector] = [69,99,108,85,49].dv(:shankar, [:two, :one, :three, :five, :four])
425
+ context Daru::MultiIndex do
426
+ # See #row
427
+ end
428
+ end
274
429
 
275
- expect(@df.shankar).to eq([99,69,108,49,85].dv(:shankar,
276
- [:one, :two, :three, :four, :five]))
277
- end
430
+ context "#[:vector]=" do
431
+ context Daru::Index do
432
+ before :each do
433
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
434
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
435
+ index: [:one, :two, :three, :four, :five])
436
+ end
278
437
 
279
- it "matches index of vector to be inserted, inserting nils where no match found" do
280
- @df.vector[:shankar] = [1,2,3].dv(:shankar, [:one, :james, :hetfield])
438
+ it "appends an Array as a Daru::Vector" do
439
+ @df[:d, :vector] = [69,99,108,85,49]
281
440
 
282
- expect(@df.shankar).to eq([1,nil,nil,nil,nil].dv(:shankar, [:one, :two, :three, :four, :five]))
283
- end
441
+ expect(@df.d.class).to eq(Daru::Vector)
442
+ end
284
443
 
285
- it "raises error for Array assignment of wrong length" do
286
- expect{
287
- @df.vector[:shiva] = [1,2,3]
288
- }.to raise_error
289
- end
444
+ it "replaces an already present vector" do
445
+ @df[:a, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
290
446
 
291
- it "appends multiple vectors at a time" do
292
- pending "Implement after initialize with array of arrays is done with."
447
+ expect(@df.a).to eq([69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five]))
448
+ end
293
449
 
294
- # Rudimentary example. Yet to think this out.
450
+ it "appends a new vector to the DataFrame" do
451
+ @df[:woo, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
295
452
 
296
- @df[:woo, :boo, :vector] = [[69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five]),
297
- [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])]
298
- end
453
+ expect(@df.vectors).to eq([:a, :b, :c, :woo].to_index)
299
454
  end
300
455
 
301
- context "#[:row]=" do
302
- before :each do
303
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
304
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
305
- index: [:one, :two, :three, :four, :five], dtype: dtype)
306
- end
456
+ it "creates an index for the new vector if not specified" do
457
+ @df[:woo, :vector] = [69,99,108,85,49]
307
458
 
308
- it "assigns specified row when Array" do
309
- @df.row[:one] = [49, 99, 59]
459
+ expect(@df.woo.index).to eq([:one, :two, :three, :four, :five].to_index)
460
+ end
310
461
 
311
- expect(@df[:one, :row]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c], dtype))
312
- expect(@df[:one, :row].index).to eq([:a, :b, :c].to_index)
313
- expect(@df[:one, :row].name) .to eq(:one)
314
- end
462
+ it "matches index of vector to be inserted with the DataFrame index" do
463
+ @df[:shankar, :vector] = [69,99,108,85,49].dv(:shankar, [:two, :one, :three, :five, :four])
315
464
 
316
- it "assigns specified row when DV" do
317
- @df[:one, :row] = [49, 99, 59].dv(nil, [:a, :b, :c], dtype)
465
+ expect(@df.shankar).to eq([99,69,108,49,85].dv(:shankar,
466
+ [:one, :two, :three, :four, :five]))
467
+ end
318
468
 
319
- expect(@df[:one, :row]).to eq([49, 99, 59].dv(:one, [:a, :b, :c], dtype))
320
- end
469
+ it "matches index of vector to be inserted, inserting nils where no match found" do
470
+ @df.vector[:shankar] = [1,2,3].dv(:shankar, [:one, :james, :hetfield])
321
471
 
322
- it "creates a new row from an Array" do
323
- @df.row[:patekar] = [9,2,11]
472
+ expect(@df.shankar).to eq([1,nil,nil,nil,nil].dv(:shankar, [:one, :two, :three, :four, :five]))
473
+ end
324
474
 
325
- expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
326
- end
475
+ it "raises error for Array assignment of wrong length" do
476
+ expect{
477
+ @df.vector[:shiva] = [1,2,3]
478
+ }.to raise_error
479
+ end
327
480
 
328
- it "creates a new row from a DV" do
329
- @df.row[:patekar] = [9,2,11].dv(nil, [:a, :b, :c])
481
+ it "appends multiple vectors at a time" do
482
+ # TODO
483
+ end
484
+ end
485
+
486
+ context Daru::MultiIndex do
487
+ pending
488
+ end
489
+ end
330
490
 
331
- expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
332
- end
491
+ context "#[]=" do
492
+ context Daru::Index do
493
+ it "assigns directly with the []= operator" do
494
+ @data_frame[:a] = [100,200,300,400,500]
495
+ expect(@data_frame).to eq(Daru::DataFrame.new({
496
+ b: [11,12,13,14,15],
497
+ a: [100,200,300,400,500],
498
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
499
+ index: [:one, :two, :three, :four, :five]))
500
+ end
501
+ end
333
502
 
334
- it "creates a new row from numeric row index and named DV" do
335
- @df.row[2] = [9,2,11].dv(nil, [:a, :b, :c])
503
+ context Daru::MultiIndex do
504
+ pending
505
+ end
506
+ end
336
507
 
337
- expect(@df[2, :row]).to eq([9,2,11].dv(nil, [:a, :b, :c]))
338
- end
508
+ context "#[:row]=" do
509
+ context Daru::Index do
510
+ before :each do
511
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
512
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
513
+ index: [:one, :two, :three, :four, :five])
514
+ end
339
515
 
340
- it "correctly aligns assigned DV by index" do
341
- @df.row[:two] = [9,2,11].dv(nil, [:b, :a, :c])
342
-
343
- expect(@df.row[:two]).to eq([2,9,11].dv(:two, [:a, :b, :c]))
344
- end
516
+ it "assigns specified row when Array" do
517
+ @df.row[:one] = [49, 99, 59]
345
518
 
346
- it "inserts nils for indexes that dont exist in the DataFrame" do
347
- @df.row[:two] = [49, 99, 59].dv(nil, [:oo, :aah, :gaah])
519
+ expect(@df[:one, :row]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
520
+ expect(@df[:one, :row].index).to eq([:a, :b, :c].to_index)
521
+ expect(@df[:one, :row].name) .to eq(:one)
522
+ end
348
523
 
349
- expect(@df.row[:two]).to eq([nil,nil,nil].dv(nil, [:a, :b, :c]))
350
- end
524
+ it "assigns specified row when DV" do
525
+ @df[:one, :row] = [49, 99, 59].dv(nil, [:a, :b, :c])
351
526
 
352
- it "correctly inserts row of a different length by matching indexes" do
353
- @df.row[:four] = [5,4,3,2,1,3].dv(nil, [:you, :have, :a, :big, :appetite, :spock])
527
+ expect(@df[:one, :row]).to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
528
+ end
354
529
 
355
- expect(@df.row[:four]).to eq([3,nil,nil].dv(:four, [:a, :b, :c]))
356
- end
530
+ it "creates a new row from an Array" do
531
+ @df.row[:patekar] = [9,2,11]
357
532
 
358
- it "raises error for row insertion by Array of wrong length" do
359
- expect{
360
- @df.row[:one] = [1,2,3,4,5,6,7]
361
- }.to raise_error
362
- end
533
+ expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
363
534
  end
364
535
 
365
- context "#row" do
366
- before :each do
367
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
368
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
369
- index: [:one, :two, :three, :four, :five], dtype: dtype)
370
- end
536
+ it "creates a new row from a DV" do
537
+ @df.row[:patekar] = [9,2,11].dv(nil, [:a, :b, :c])
371
538
 
372
- it "creates an index for assignment if not already specified" do
373
- @df.row[:one] = [49, 99, 59]
539
+ expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
540
+ end
374
541
 
375
- expect(@df[:one, :row]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
376
- expect(@df[:one, :row].index).to eq([:a, :b, :c].to_index)
377
- expect(@df[:one, :row].name) .to eq(:one)
378
- end
542
+ it "creates a new row from numeric row index and named DV" do
543
+ @df.row[2] = [9,2,11].dv(nil, [:a, :b, :c])
379
544
 
380
- it "returns a DataFrame when specifying numeric Range" do
381
- expect(@df.row[0..2]).to eq(
382
- Daru::DataFrame.new({b: [11,12,13], a: [1,2,3],
383
- c: [11,22,33]}, order: [:a, :b, :c],
384
- index: [:one, :two, :three], dtype: dtype)
385
- )
386
- end
545
+ expect(@df[2, :row]).to eq([9,2,11].dv(nil, [:a, :b, :c]))
546
+ end
387
547
 
388
- it "returns a DataFrame when specifying symbolic Range" do
389
- expect(@df.row[:one..:three]).to eq(
390
- Daru::DataFrame.new({b: [11,12,13], a: [1,2,3],
391
- c: [11,22,33]}, order: [:a, :b, :c],
392
- index: [:one, :two, :three], dtype: dtype)
393
- )
394
- end
548
+ it "correctly aligns assigned DV by index" do
549
+ @df.row[:two] = [9,2,11].dv(nil, [:b, :a, :c])
550
+
551
+ expect(@df.row[:two]).to eq([2,9,11].dv(:two, [:a, :b, :c]))
395
552
  end
396
553
 
397
- context "#vector" do
398
- it "appends an Array as a Daru::Vector" do
399
- @data_frame[:d, :vector] = [69,99,108,85,49]
554
+ it "inserts nils for indexes that dont exist in the DataFrame" do
555
+ @df.row[:two] = [49, 99, 59].dv(nil, [:oo, :aah, :gaah])
400
556
 
401
- expect(@data_frame.d.class).to eq(Daru::Vector)
402
- end
557
+ expect(@df.row[:two]).to eq([nil,nil,nil].dv(nil, [:a, :b, :c]))
403
558
  end
404
559
 
405
- context "#==" do
406
- it "compares by vectors, index and values of a DataFrame (ignores name)" do
407
- a = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
408
- order: [:a, :b], index: [:one, :two, :three, :four, :five], dtype: dtype)
560
+ it "correctly inserts row of a different length by matching indexes" do
561
+ @df.row[:four] = [5,4,3,2,1,3].dv(nil, [:you, :have, :a, :big, :appetite, :spock])
409
562
 
410
- b = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
411
- order: [:a, :b], index: [:one, :two, :three, :four, :five], dtype: dtype)
563
+ expect(@df.row[:four]).to eq([3,nil,nil].dv(:four, [:a, :b, :c]))
564
+ end
412
565
 
413
- expect(a).to eq(b)
414
- end
566
+ it "raises error for row insertion by Array of wrong length" do
567
+ expect{
568
+ @df.row[:one] = [1,2,3,4,5,6,7]
569
+ }.to raise_error
415
570
  end
571
+ end
416
572
 
417
- context "#dup" do
418
- it "dups every data structure inside DataFrame" do
419
- clo = @data_frame.dup
573
+ context Daru::MultiIndex do
574
+ pending
575
+ end
576
+ end
420
577
 
421
- expect(clo.object_id) .not_to eq(@data_frame.object_id)
422
- expect(clo.vectors.object_id).not_to eq(@data_frame.object_id)
423
- expect(clo.index.object_id) .not_to eq(@data_frame.object_id)
578
+ context "#row" do
579
+ context Daru::Index do
580
+ before :each do
581
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
582
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
583
+ index: [:one, :two, :three, :four, :five])
584
+ end
424
585
 
425
- @data_frame.each_vector_with_index do |vector, index|
426
- expect(vector.object_id).not_to eq(clo.vector[index].object_id)
427
- end
428
- end
586
+ it "creates an index for assignment if not already specified" do
587
+ @df.row[:one] = [49, 99, 59]
588
+
589
+ expect(@df[:one, :row]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
590
+ expect(@df[:one, :row].index).to eq([:a, :b, :c].to_index)
591
+ expect(@df[:one, :row].name) .to eq(:one)
429
592
  end
430
593
 
431
- context "#each_vector" do
432
- it "iterates over all vectors" do
433
- ret = @data_frame.each_vector do |vector|
434
- expect(vector.index).to eq([:one, :two, :three, :four, :five].to_index)
435
- expect(vector.class).to eq(Daru::Vector)
436
- end
594
+ it "returns a DataFrame when specifying numeric Range" do
595
+ expect(@df.row[0..2]).to eq(
596
+ Daru::DataFrame.new({b: [11,12,13], a: [1,2,3],
597
+ c: [11,22,33]}, order: [:a, :b, :c],
598
+ index: [:one, :two, :three])
599
+ )
600
+ end
437
601
 
438
- expect(ret).to eq(@data_frame)
439
- end
602
+ it "returns a DataFrame when specifying symbolic Range" do
603
+ expect(@df.row[:one..:three]).to eq(
604
+ Daru::DataFrame.new({b: [11,12,13], a: [1,2,3],
605
+ c: [11,22,33]}, order: [:a, :b, :c],
606
+ index: [:one, :two, :three])
607
+ )
608
+ end
609
+ end
610
+
611
+ context Daru::MultiIndex do
612
+ it "returns a Vector when specifying integer index" do
613
+ expect(@df_mi.row[0]).to eq(Daru::Vector.new([11,1,11,1], index: @order_mi))
440
614
  end
441
615
 
442
- context "#each_vector_with_index" do
443
- it "iterates over vectors with index" do
444
- idxs = []
445
- ret = @data_frame.each_vector_with_index do |vector, index|
446
- idxs << index
447
- expect(vector.index).to eq([:one, :two, :three, :four, :five].to_index)
448
- expect(vector.class).to eq(Daru::Vector)
449
- end
616
+ it "returns a DataFrame when specifying numeric range" do
617
+ sub_index = Daru::MultiIndex.new([
618
+ [:a,:one,:bar],
619
+ [:a,:one,:baz],
620
+ [:a,:two,:bar],
621
+ [:a,:two,:baz],
622
+ [:b,:one,:bar],
623
+ [:b,:two,:bar],
624
+ [:b,:two,:baz],
625
+ [:b,:one,:foo]
626
+ ])
627
+
628
+ expect(@df_mi.row[0..1]).to eq(Daru::DataFrame.new([
629
+ [11,12,13,14,11,12,13,14],
630
+ [1,2,3,4,1,2,3,4],
631
+ [11,12,13,14,11,12,13,14],
632
+ [1,2,3,4,1,2,3,4]
633
+ ], order: @order_mi, index: sub_index, name: :numeric_range))
634
+ end
450
635
 
451
- expect(idxs).to eq([:a, :b, :c])
636
+ it "returns a Vector when specifying complete tuple" do
637
+ expect(@df_mi.row[:c,:two,:foo]).to eq(Daru::Vector.new([13,3,13,3], index: @order_mi))
638
+ end
452
639
 
453
- expect(ret).to eq(@data_frame)
454
- end
640
+ it "returns DataFrame when specifying first layer of MultiIndex" do
641
+ sub_index = Daru::MultiIndex.new([
642
+ [:one,:bar],
643
+ [:one,:baz],
644
+ [:two,:foo],
645
+ [:two,:bar]
646
+ ])
647
+ expect(@df_mi.row[:c]).to eq(Daru::DataFrame.new([
648
+ [11,12,13,14],
649
+ [1,2,3,4],
650
+ [11,12,13,14],
651
+ [1,2,3,4]
652
+ ], index: sub_index, order: @order_mi))
455
653
  end
456
654
 
457
- context "#each_row" do
458
- it "iterates over rows" do
459
- ret = @data_frame.each_row do |row|
460
- expect(row.index).to eq([:a, :b, :c].to_index)
461
- expect(row.class).to eq(Daru::Vector)
462
- end
655
+ it "returns DataFrame when specifying first and second layer of MultiIndex" do
656
+ sub_index = Daru::MultiIndex.new([
657
+ [:bar],
658
+ [:baz]
659
+ ])
660
+ expect(@df_mi.row[:c,:one]).to eq(Daru::DataFrame.new([
661
+ [11,12],
662
+ [1,2],
663
+ [11,12],
664
+ [1,2]
665
+ ], index: sub_index, order: @order_mi))
666
+ end
667
+ end
668
+ end
463
669
 
464
- expect(ret).to eq(@data_frame)
465
- end
670
+ context "#vector" do
671
+ context Daru::Index do
672
+ it "appends an Array as a Daru::Vector" do
673
+ @data_frame[:d, :vector] = [69,99,108,85,49]
674
+
675
+ expect(@data_frame.d.class).to eq(Daru::Vector)
466
676
  end
677
+ end
467
678
 
468
- context "#each_row_with_index" do
469
- it "iterates over rows with indexes" do
470
- idxs = []
471
- ret = @data_frame.each_row_with_index do |row, idx|
472
- idxs << idx
473
- expect(row.index).to eq([:a, :b, :c].to_index)
474
- expect(row.class).to eq(Daru::Vector)
475
- end
679
+ context Daru::MultiIndex do
680
+ it "accesses vector with an integer index" do
681
+ expect(@df_mi.vector[0]).to eq(Daru::Vector.new(@vector_arry1,
682
+ index: @multi_index))
683
+ end
476
684
 
477
- expect(idxs).to eq([:one, :two, :three, :four, :five])
478
- expect(ret) .to eq(@data_frame)
479
- end
685
+ it "returns a vector when specifying full tuple" do
686
+ expect(@df_mi.vector[:a, :one, :bar]).to eq(Daru::Vector.new(@vector_arry1,
687
+ index: @multi_index))
480
688
  end
481
689
 
482
- context "#map_vectors" do
483
- it "iterates over vectors and returns a modified DataFrame" do
484
- ans = Daru::DataFrame.new({b: [21,22,23,24,25], a: [11,12,13,14,15],
485
- c: [21,32,43,54,65]}, order: [:a, :b, :c],
486
- index: [:one, :two, :three, :four, :five], dtype: dtype)
690
+ it "returns DataFrame when specified first layer of MultiIndex" do
691
+ sub_order = Daru::MultiIndex.new([
692
+ [:one, :bar],
693
+ [:two, :baz]
694
+ ])
695
+ expect(@df_mi.vector[:a]).to eq(Daru::DataFrame.new([
696
+ @vector_arry1,
697
+ @vector_arry2
698
+ ], index: @multi_index, order: sub_order))
699
+ end
487
700
 
488
- ret = @data_frame.map_vectors do |vector|
489
- vector = vector.map { |e| e += 10}
490
- end
701
+ it "returns DataFrame when specified first and second layer of MultiIndex" do
702
+ sub_order = Daru::MultiIndex.new([
703
+ [:bar]
704
+ ])
705
+ expect(@df_mi.vector[:a, :one]).to eq(Daru::DataFrame.new([
706
+ @vector_arry1
707
+ ], index: @multi_index, order: sub_order))
708
+ end
709
+ end
710
+ end
711
+
712
+ context "#==" do
713
+ it "compares by vectors, index and values of a DataFrame (ignores name)" do
714
+ a = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
715
+ order: [:a, :b], index: [:one, :two, :three, :four, :five])
716
+
717
+ b = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
718
+ order: [:a, :b], index: [:one, :two, :three, :four, :five])
719
+
720
+ expect(a).to eq(b)
721
+ end
722
+ end
723
+
724
+ context "#dup" do
725
+ it "dups every data structure inside DataFrame" do
726
+ clo = @data_frame.dup
727
+
728
+ expect(clo.object_id) .not_to eq(@data_frame.object_id)
729
+ expect(clo.vectors.object_id).not_to eq(@data_frame.object_id)
730
+ expect(clo.index.object_id) .not_to eq(@data_frame.object_id)
731
+
732
+ @data_frame.each_vector_with_index do |vector, index|
733
+ expect(vector.object_id).not_to eq(clo.vector[index].object_id)
734
+ end
735
+ end
736
+ end
491
737
 
492
- expect(ret).to eq(ans)
493
- expect(ret == @data_frame).to eq(false)
738
+ context "#each_vector" do
739
+ context Daru::Index do
740
+ it "iterates over all vectors" do
741
+ ret = @data_frame.each_vector do |vector|
742
+ expect(vector.index).to eq([:one, :two, :three, :four, :five].to_index)
743
+ expect(vector.class).to eq(Daru::Vector)
494
744
  end
745
+
746
+ expect(ret).to eq(@data_frame)
495
747
  end
496
748
 
497
- context "#map_vectors_with_index" do
498
- it "iterates over vectors with index and returns a modified DataFrame" do
499
- ans = Daru::DataFrame.new({b: [21,22,23,24,25], a: [11,12,13,14,15],
500
- c: [21,32,43,54,65]}, order: [:a, :b, :c],
501
- index: [:one, :two, :three, :four, :five], dtype: dtype)
749
+ it "returns Enumerable if no block specified" do
750
+ ret = @data_frame.each_vector
751
+ expect(ret.is_a?(Enumerator)).to eq(true)
752
+ end
753
+ end
502
754
 
503
- idx = []
504
- ret = @data_frame.map_vectors_with_index do |vector, index|
505
- idx << index
506
- vector = vector.map { |e| e += 10}
507
- end
755
+ context Daru::MultiIndex do
508
756
 
509
- expect(ret).to eq(ans)
510
- expect(idx).to eq([:a, :b, :c])
511
- end
757
+ end
758
+ end
759
+
760
+ context "#each_vector_with_index" do
761
+ it "iterates over vectors with index" do
762
+ idxs = []
763
+ ret = @data_frame.each_vector_with_index do |vector, index|
764
+ idxs << index
765
+ expect(vector.index).to eq([:one, :two, :three, :four, :five].to_index)
766
+ expect(vector.class).to eq(Daru::Vector)
512
767
  end
513
768
 
514
- context "#map_rows" do
515
- it "iterates over rows and returns a modified DataFrame" do
516
- ans = Daru::DataFrame.new({b: [121, 144, 169, 196, 225], a: [1,4,9,16,25],
517
- c: [121, 484, 1089, 1936, 3025]}, order: [:a, :b, :c],
518
- index: [:one, :two, :three, :four, :five], dtype: dtype)
769
+ expect(idxs).to eq([:a, :b, :c])
770
+
771
+ expect(ret).to eq(@data_frame)
772
+ end
773
+ end
774
+
775
+ context "#each_row" do
776
+ it "iterates over rows" do
777
+ ret = @data_frame.each_row do |row|
778
+ expect(row.index).to eq([:a, :b, :c].to_index)
779
+ expect(row.class).to eq(Daru::Vector)
780
+ end
519
781
 
520
- ret = @data_frame.map_rows do |row|
521
- expect(row.class).to eq(Daru::Vector)
522
- row = row.map { |e| e*e }
523
- end
782
+ expect(ret).to eq(@data_frame)
783
+ end
784
+ end
524
785
 
525
- expect(ret).to eq(ans)
526
- end
786
+ context "#each_row_with_index" do
787
+ it "iterates over rows with indexes" do
788
+ idxs = []
789
+ ret = @data_frame.each_row_with_index do |row, idx|
790
+ idxs << idx
791
+ expect(row.index).to eq([:a, :b, :c].to_index)
792
+ expect(row.class).to eq(Daru::Vector)
527
793
  end
528
794
 
529
- context "#map_rows_with_index" do
530
- it "iterates over rows with index and returns a modified DataFrame" do
531
- ans = Daru::DataFrame.new({b: [121, 144, 169, 196, 225], a: [1,4,9,16,25],
532
- c: [121, 484, 1089, 1936, 3025]},order: [:a, :b, :c],
533
- index: [:one, :two, :three, :four, :five], dtype: dtype)
795
+ expect(idxs).to eq([:one, :two, :three, :four, :five])
796
+ expect(ret) .to eq(@data_frame)
797
+ end
798
+ end
534
799
 
535
- idx = []
536
- ret = @data_frame.map_rows_with_index do |row, index|
537
- idx << index
538
- expect(row.class).to eq(Daru::Vector)
539
- row = row.map { |e| e*e }
540
- end
800
+ context "#map_vectors" do
801
+ it "iterates over vectors and returns a modified DataFrame" do
802
+ ans = Daru::DataFrame.new({b: [21,22,23,24,25], a: [11,12,13,14,15],
803
+ c: [21,32,43,54,65]}, order: [:a, :b, :c],
804
+ index: [:one, :two, :three, :four, :five])
541
805
 
542
- expect(ret).to eq(ans)
543
- expect(idx).to eq([:one, :two, :three, :four, :five])
544
- end
806
+ ret = @data_frame.map_vectors do |vector|
807
+ vector = vector.map { |e| e += 10}
545
808
  end
546
809
 
547
- context "#delete_vector" do
548
- it "deletes the specified vector" do
549
- @data_frame.delete_vector :a
810
+ expect(ret).to eq(ans)
811
+ expect(ret == @data_frame).to eq(false)
812
+ end
813
+ end
814
+
815
+ context "#map_vectors!" do
816
+ it "maps vectors (bang)" do
817
+ ans = Daru::DataFrame.new({b: [21,22,23,24,25], a: [11,12,13,14,15],
818
+ c: [21,32,43,54,65]}, order: [:a, :b, :c],
819
+ index: [:one, :two, :three, :four, :five])
550
820
 
551
- expect(@data_frame).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
552
- c: [11,22,33,44,55]}, order: [:b, :c],
553
- index: [:one, :two, :three, :four, :five], dtype: dtype))
554
- end
821
+ @data_frame.map_vectors! do |vector|
822
+ vector.map! { |e| e += 10}
555
823
  end
556
824
 
557
- context "#delete_row" do
558
- it "deletes the specified row" do
559
- @data_frame.delete_row :one
825
+ expect(@data_frame).to eq(ans)
826
+ end
827
+ end
828
+
829
+ context "#map_vectors_with_index" do
830
+ it "iterates over vectors with index and returns a modified DataFrame" do
831
+ ans = Daru::DataFrame.new({b: [21,22,23,24,25], a: [11,12,13,14,15],
832
+ c: [21,32,43,54,65]}, order: [:a, :b, :c],
833
+ index: [:one, :two, :three, :four, :five])
560
834
 
561
- expect(@data_frame).to eq(Daru::DataFrame.new({b: [12,13,14,15], a: [2,3,4,5],
562
- c: [22,33,44,55]}, order: [:a, :b, :c], index: [:two, :three, :four, :five], dtype: dtype))
563
- end
835
+ idx = []
836
+ ret = @data_frame.map_vectors_with_index do |vector, index|
837
+ idx << index
838
+ vector = vector.map { |e| e += 10}
564
839
  end
565
840
 
566
- context "#keep_row_if", :focus => true do
567
- it "keeps row if block evaluates to true" do
568
- df = Daru::DataFrame.new({b: [10,12,20,23,30], a: [50,30,30,1,5],
569
- c: [10,20,30,40,50]}, order: [:a, :b, :c],
570
- index: [:one, :two, :three, :four, :five], dtype: dtype)
841
+ expect(ret).to eq(ans)
842
+ expect(idx).to eq([:a, :b, :c])
843
+ end
844
+ end
571
845
 
572
- df.keep_row_if do |row|
573
- row[:a] % 10 == 0
574
- end
575
- # TODO: write expectation
576
- end
846
+ context "#map_rows" do
847
+ it "iterates over rows and returns a modified DataFrame" do
848
+ ans = Daru::DataFrame.new({b: [121, 144, 169, 196, 225], a: [1,4,9,16,25],
849
+ c: [121, 484, 1089, 1936, 3025]}, order: [:a, :b, :c],
850
+ index: [:one, :two, :three, :four, :five])
851
+
852
+ ret = @data_frame.map_rows do |row|
853
+ expect(row.class).to eq(Daru::Vector)
854
+ row = row.map { |e| e*e }
577
855
  end
578
856
 
579
- context "#keep_vector_if" do
580
- it "keeps vector if block evaluates to true" do
581
- @data_frame.keep_vector_if do |vector|
582
- vector == [1,2,3,4,5].dv(nil, [:one, :two, :three, :four, :five])
583
- end
857
+ expect(ret).to eq(ans)
858
+ end
859
+ end
584
860
 
585
- expect(@data_frame).to eq(Daru::DataFrame.new({a: [1,2,3,4,5]}, order: [:a],
586
- index: [:one, :two, :three, :four, :five], dtype: dtype))
587
- end
861
+ context "#map_rows_with_index" do
862
+ it "iterates over rows with index and returns a modified DataFrame" do
863
+ ans = Daru::DataFrame.new({b: [121, 144, 169, 196, 225], a: [1,4,9,16,25],
864
+ c: [121, 484, 1089, 1936, 3025]},order: [:a, :b, :c],
865
+ index: [:one, :two, :three, :four, :five])
866
+
867
+ idx = []
868
+ ret = @data_frame.map_rows_with_index do |row, index|
869
+ idx << index
870
+ expect(row.class).to eq(Daru::Vector)
871
+ row = row.map { |e| e*e }
588
872
  end
589
873
 
590
- context "#filter_rows" do
591
- it "filters rows" do
592
- df = Daru::DataFrame.new({a: [1,2,3], b: [2,3,4]})
874
+ expect(ret).to eq(ans)
875
+ expect(idx).to eq([:one, :two, :three, :four, :five])
876
+ end
877
+ end
878
+
879
+ context "#delete_vector" do
880
+ context Daru::Index do
881
+ it "deletes the specified vector" do
882
+ @data_frame.delete_vector :a
883
+
884
+ expect(@data_frame).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
885
+ c: [11,22,33,44,55]}, order: [:b, :c],
886
+ index: [:one, :two, :three, :four, :five]))
887
+ end
888
+ end
889
+
890
+ context Daru::MultiIndex do
891
+ pending
892
+ end
893
+ end
894
+
895
+ context "#delete_row" do
896
+ it "deletes the specified row" do
897
+ @data_frame.delete_row :one
898
+
899
+ expect(@data_frame).to eq(Daru::DataFrame.new({b: [12,13,14,15], a: [2,3,4,5],
900
+ c: [22,33,44,55]}, order: [:a, :b, :c], index: [:two, :three, :four, :five]))
901
+ end
902
+ end
593
903
 
594
- a = df.filter_rows do |row|
595
- row[:a] % 2 == 0
596
- end
904
+ context "#keep_row_if" do
905
+ pending "changing row from under the iterator trips this"
906
+ it "keeps row if block evaluates to true" do
907
+ df = Daru::DataFrame.new({b: [10,12,20,23,30], a: [50,30,30,1,5],
908
+ c: [10,20,30,40,50]}, order: [:a, :b, :c],
909
+ index: [:one, :two, :three, :four, :five])
597
910
 
598
- expect(a).to eq(Daru::DataFrame.new({a: [2], b: [3]}, order: [:a, :b], index: [1]))
911
+ df.keep_row_if do |row|
912
+ row[:a] % 10 == 0
913
+ end
914
+ # TODO: write expectation
915
+ end
916
+ end
917
+
918
+ context "#keep_vector_if" do
919
+ it "keeps vector if block evaluates to true" do
920
+ @data_frame.keep_vector_if do |vector|
921
+ vector == [1,2,3,4,5].dv(nil, [:one, :two, :three, :four, :five])
922
+ end
923
+
924
+ expect(@data_frame).to eq(Daru::DataFrame.new({a: [1,2,3,4,5]}, order: [:a],
925
+ index: [:one, :two, :three, :four, :five]))
926
+ end
927
+ end
928
+
929
+ context "#filter_rows" do
930
+ context Daru::Index do
931
+ it "filters rows" do
932
+ df = Daru::DataFrame.new({a: [1,2,3], b: [2,3,4]})
933
+
934
+ a = df.filter_rows do |row|
935
+ row[:a] % 2 == 0
599
936
  end
937
+
938
+ expect(a).to eq(Daru::DataFrame.new({a: [2], b: [3]}, order: [:a, :b], index: [1]))
600
939
  end
940
+ end
601
941
 
602
- context "#filter_vectors" do
603
- it "filters vectors" do
604
- df = Daru::DataFrame.new({a: [1,2,3], b: [2,3,4]}, dtype: dtype)
942
+ context Daru::MultiIndex do
943
+ pending
944
+ end
945
+ end
605
946
 
606
- a = df.filter_vectors do |vector|
607
- vector[0] == 1
608
- end
947
+ context "#filter_vectors" do
948
+ context Daru::Index do
949
+ it "filters vectors" do
950
+ df = Daru::DataFrame.new({a: [1,2,3], b: [2,3,4]})
609
951
 
610
- expect(a).to eq(Daru::DataFrame.new({a: [1,2,3]}, dtype: dtype))
952
+ a = df.filter_vectors do |vector|
953
+ vector[0] == 1
611
954
  end
955
+
956
+ expect(a).to eq(Daru::DataFrame.new({a: [1,2,3]}))
612
957
  end
958
+ end
613
959
 
614
- context "#to_a" do
615
- it "converts DataFrame into array of hashes" do
616
- arry = @data_frame.to_a
960
+ context Daru::MultiIndex do
961
+ pending
962
+ end
963
+ end
617
964
 
618
- expect(arry).to eq(
965
+ context "#to_a" do
966
+ context Daru::Index do
967
+ it "converts DataFrame into array of hashes" do
968
+ arry = @data_frame.to_a
969
+
970
+ expect(arry).to eq(
971
+ [
619
972
  [
620
- [
621
- {a: 1, b: 11, c: 11},
622
- {a: 2, b: 12, c: 22},
623
- {a: 3, b: 13, c: 33},
624
- {a: 4, b: 14, c: 44},
625
- {a: 5, b: 15, c: 55}
626
- ],
627
- [
628
- :one, :two, :three, :four, :five
629
- ]
630
- ])
631
- end
973
+ {a: 1, b: 11, c: 11},
974
+ {a: 2, b: 12, c: 22},
975
+ {a: 3, b: 13, c: 33},
976
+ {a: 4, b: 14, c: 44},
977
+ {a: 5, b: 15, c: 55}
978
+ ],
979
+ [
980
+ :one, :two, :three, :four, :five
981
+ ]
982
+ ])
983
+ end
984
+ end
985
+
986
+ context Daru::MultiIndex do
987
+ pending
988
+ end
989
+ end
990
+
991
+ context "#recast" do
992
+ it "recasts underlying vectors" do
993
+ @data_frame.recast a: :nmatrix, c: :nmatrix
994
+
995
+ expect(@data_frame.a.dtype).to eq(:nmatrix)
996
+ expect(@data_frame.b.dtype).to eq(:array)
997
+ expect(@data_frame.c.dtype).to eq(:nmatrix)
998
+ end
999
+ end
1000
+
1001
+ context "#sort" do
1002
+ context Daru::Index do
1003
+ before :each do
1004
+ @df = Daru::DataFrame.new({a: [5,1,-6,7,5,5], b: [-2,-1,5,3,9,1], c: ['a','aa','aaa','aaaa','aaaaa','aaaaaa']})
1005
+ end
1006
+
1007
+ it "sorts according to given vector order (bang)" do
1008
+ a_sorter = lambda { |a,b| a <=> b }
1009
+ ans = @df.sort([:a], by: { a: a_sorter })
1010
+
1011
+ expect(ans).to eq(
1012
+ Daru::DataFrame.new({a: [-6,1,5,5,5,7], b: [5,-1,9,1,-2,3], c: ['aaa','aa','aaaaa','aaaaaa','a','aaaa']},
1013
+ index: [2,1,4,5,0,3])
1014
+ )
1015
+ expect(ans).to_not eq(@df)
1016
+ end
1017
+
1018
+ it "sorts according to vector order using default lambdas (index re ordered according to the last vector) (bang)" do
1019
+ ans = @df.sort([:a, :b])
1020
+ expect(ans).to eq(
1021
+ Daru::DataFrame.new({a: [-6,1,5,5,5,7], b: [5,-1,-2,1,9,3], c: ['aaa','aa','a','aaaaaa','aaaaa','aaaa']},
1022
+ index: [2,1,0,5,4,3])
1023
+ )
1024
+ expect(ans).to_not eq(@df)
1025
+ end
1026
+ end
1027
+
1028
+ context Daru::MultiIndex do
1029
+ pending
1030
+ end
1031
+ end
1032
+
1033
+ context "#sort!" do
1034
+ context Daru::Index do
1035
+ before :each do
1036
+ @df = Daru::DataFrame.new({a: [5,1,-6,7,5,5], b: [-2,-1,5,3,9,1],
1037
+ c: ['a','aa','aaa','aaaa','aaaaa','aaaaaa']})
1038
+ end
1039
+
1040
+ it "sorts according to given vector order (bang)" do
1041
+ a_sorter = lambda { |a,b| a <=> b }
1042
+
1043
+ expect(@df.sort!([:a], by: { a: a_sorter })).to eq(
1044
+ Daru::DataFrame.new({a: [-6,1,5,5,5,7], b: [5,-1,9,1,-2,3],
1045
+ c: ['aaa','aa','aaaaa','aaaaaa','a','aaaa']}, index: [2,1,4,5,0,3])
1046
+ )
1047
+ end
1048
+
1049
+ it "sorts according to vector order using default lambdas (index re ordered according to the last vector) (bang)" do
1050
+ expect(@df.sort!([:a, :b])).to eq(
1051
+ Daru::DataFrame.new({a: [-6,1,5,5,5,7], b: [5,-1,-2,1,9,3], c: ['aaa','aa','a','aaaaaa','aaaaa','aaaa']},
1052
+ index: [2,1,0,5,4,3])
1053
+ )
1054
+ end
1055
+
1056
+ it "sorts both vectors in descending order" do
1057
+ expect(@df.sort!([:a,:b], ascending: [false, false])).to eq(
1058
+ Daru::DataFrame.new({a: [7,5,5,5,1,-6], b: [3,9,1,-2,-1,5], c: ['aaaa','aaaaa','aaaaaa', 'a','aa', 'aaa'] },
1059
+ index: [3,4,5,0,1,2])
1060
+ )
1061
+ end
1062
+
1063
+ it "sorts one vector in desc and other is asc" do
1064
+ expect(@df.sort!([:a, :b], ascending: [false, true])).to eq(
1065
+ Daru::DataFrame.new({a: [7,5,5,5,1,-6], b: [3,-2,1,9,-1,5], c: ['aaaa','a','aaaaaa','aaaaa','aa','aaa']},
1066
+ index: [3,0,5,4,1,2])
1067
+ )
1068
+ end
1069
+
1070
+ it "sorts many vectors" do
1071
+ d = Daru::DataFrame.new({a: [1,1,1,222,44,5,5,544], b: [44,44,333,222,111,554,22,3], c: [3,2,5,3,3,1,5,5]})
1072
+
1073
+ expect(d.sort!([:a, :b, :c], ascending: [false, true, false])).to eq(
1074
+ Daru::DataFrame.new({a: [544,222,44,5,5,1,1,1], b: [3,222,111,22,554,44,44,333], c: [5,3,3,5,1,3,2,5]},
1075
+ index: [7,3,4,6,5,0,1,2])
1076
+ )
1077
+ end
1078
+ end
1079
+
1080
+ context Daru::MultiIndex do
1081
+ pending
1082
+ it "sorts the DataFrame when specified full tuple" do
1083
+ @df_mi.sort([[:a,:one,:bar]])
632
1084
  end
633
1085
  end
1086
+ end
1087
+
1088
+ context "#reindex" do
1089
+ it "sets a new sequential index for DF and its underlying vectors" do
1090
+ a = @data_frame.reindex(:seq)
1091
+
1092
+ expect(a).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
1093
+ a: [1,2,3,4,5], c: [11,22,33,44,55]}, order: [:a, :b, :c]))
1094
+ expect(a).to_not eq(@data_frame)
1095
+
1096
+ expect(a.a.index).to eq(Daru::Index.new(5))
1097
+ expect(a.b.index).to eq(Daru::Index.new(5))
1098
+ expect(a.c.index).to eq(Daru::Index.new(5))
1099
+ end
1100
+
1101
+ it "sets a new index for the data frame and its underlying vectors" do
1102
+ a = @data_frame.reindex([:a,:b,:c,:d,:e])
1103
+
1104
+ expect(a).to eq(Daru::DataFrame.new(
1105
+ {b: [11,12,13,14,15], a: [1,2,3,4,5], c: [11,22,33,44,55]},
1106
+ order: [:a, :b, :c], index: [:a,:b,:c,:d,:e]))
1107
+ expect(a).to_not eq(@data_frame)
1108
+
1109
+ expect(a.a.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1110
+ expect(a.b.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1111
+ expect(a.c.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1112
+ end
1113
+ end
1114
+
1115
+ context "#reindex!" do
1116
+ context Daru::Index do
1117
+ it "sets a new sequential index for DF and its underlying vectors" do
1118
+ expect(@data_frame.reindex!(:seq)).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
1119
+ a: [1,2,3,4,5], c: [11,22,33,44,55]}, order: [:a, :b, :c]))
1120
+ expect(@data_frame.a.index).to eq(Daru::Index.new(5))
1121
+ expect(@data_frame.b.index).to eq(Daru::Index.new(5))
1122
+ expect(@data_frame.c.index).to eq(Daru::Index.new(5))
1123
+ end
1124
+
1125
+ it "sets a new index for the data frame and its underlying vectors" do
1126
+ expect(@data_frame.reindex!([:a,:b,:c,:d,:e])).to eq(Daru::DataFrame.new(
1127
+ {b: [11,12,13,14,15], a: [1,2,3,4,5], c: [11,22,33,44,55]},
1128
+ order: [:a, :b, :c], index: [:a,:b,:c,:d,:e]))
1129
+ expect(@data_frame.a.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1130
+ expect(@data_frame.b.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1131
+ expect(@data_frame.c.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1132
+ end
1133
+ end
1134
+
1135
+ context Daru::MultiIndex do
1136
+ pending "feature manually tested. write tests"
1137
+ end
1138
+ end
1139
+
1140
+ context "#to_matrix" do
1141
+ before do
1142
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
1143
+ c: [11,22,33,44,55], d: [5,4,nil,2,1], e: ['this', 'has', 'string','data','too']},
1144
+ order: [:a, :b, :c,:d,:e],
1145
+ index: [:one, :two, :three, :four, :five])
1146
+ end
1147
+
1148
+ it "concats numeric non-nil vectors to Matrix" do
1149
+ expect(@df.to_matrix).to eq(Matrix[
1150
+ [1,11,11,5],
1151
+ [2,12,22,4],
1152
+ [3,13,33,nil],
1153
+ [4,14,44,2],
1154
+ [5,15,55,1]
1155
+ ])
1156
+ end
1157
+ end
1158
+
1159
+ context "#to_nmatrix" do
1160
+ before do
1161
+ @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
1162
+ c: [11,22,33,44,55], d: [5,4,nil,2,1], e: ['this', 'has', 'string','data','too']},
1163
+ order: [:a, :b, :c,:d,:e],
1164
+ index: [:one, :two, :three, :four, :five])
1165
+ end
1166
+
1167
+ it "concats numeric non-nil vectors to NMatrix" do
1168
+ expect(@df.to_nmatrix).to eq(NMatrix.new([5,3],
1169
+ [1,11,11,
1170
+ 2,12,22,
1171
+ 3,13,33,
1172
+ 4,14,44,
1173
+ 5,15,55]
1174
+ ))
1175
+ end
1176
+ end
1177
+
1178
+ context "#transpose" do
1179
+ context Daru::Index do
1180
+ it "transposes a DataFrame including row and column indexing" do
1181
+ expect(@data_frame.transpose).to eq(Daru::DataFrame.new({
1182
+ one: [1,11,11],
1183
+ two: [2,12,22],
1184
+ three: [3,13,33],
1185
+ four: [4,14,44],
1186
+ five: [5,15,55]
1187
+ }, index: [:a, :b, :c],
1188
+ order: [:one, :two, :three, :four, :five])
1189
+ )
1190
+ end
1191
+ end
1192
+
1193
+ context Daru::MultiIndex do
1194
+ it "transposes a DataFrame including row and column indexing" do
1195
+ expect(@df_mi.transpose).to eq(Daru::DataFrame.new([
1196
+ @vector_arry1,
1197
+ @vector_arry2,
1198
+ @vector_arry1,
1199
+ @vector_arry2].transpose, index: @order_mi, order: @multi_index))
1200
+ end
1201
+ end
1202
+ end
1203
+
1204
+ context "#pivot_table" do
1205
+ before do
1206
+ @df = Daru::DataFrame.new({
1207
+ a: ['foo' , 'foo', 'foo', 'foo', 'foo', 'bar', 'bar', 'bar', 'bar'],
1208
+ b: ['one' , 'one', 'one', 'two', 'two', 'one', 'one', 'two', 'two'],
1209
+ c: ['small','large','large','small','small','large','small','large','small'],
1210
+ d: [1,2,2,3,3,4,5,6,7],
1211
+ e: [2,4,4,6,6,8,10,12,14]
1212
+ })
1213
+ end
1214
+
1215
+ it "creates row index as per (single) index argument and default aggregates to mean" do
1216
+ expect(@df.pivot_table(index: [:a])).to eq(Daru::DataFrame.new({
1217
+ d: [5.5,2.2],
1218
+ e: [11.0,4.4]
1219
+ }, index: [:bar, :foo]))
1220
+ end
1221
+
1222
+ it "creates row index as per (double) index argument and default aggregates to mean" do
1223
+ agg_mi = Daru::MultiIndex.new(
1224
+ [
1225
+ [:bar, :large],
1226
+ [:bar, :small],
1227
+ [:foo, :large],
1228
+ [:foo, :small]
1229
+ ]
1230
+ )
1231
+ expect(@df.pivot_table(index: [:a, :c]).round(2)).to eq(Daru::DataFrame.new({
1232
+ d: [5.0 , 6.0, 2.0, 2.33],
1233
+ e: [10.0, 12.0, 4.0, 4.67]
1234
+ }, index: agg_mi))
1235
+ end
1236
+
1237
+ it "creates row and vector index as per (single) index and (single) vectors args" do
1238
+ agg_vectors = Daru::MultiIndex.new([
1239
+ [:d, :one],
1240
+ [:d, :two],
1241
+ [:e, :one],
1242
+ [:e, :two]
1243
+ ])
1244
+ agg_index = Daru::MultiIndex.new(
1245
+ [
1246
+ [:bar],
1247
+ [:foo]
1248
+ ]
1249
+ )
1250
+
1251
+ expect(@df.pivot_table(index: [:a], vectors: [:b]).round(2)).to eq(Daru::DataFrame.new(
1252
+ [
1253
+ [4.5, 1.67],
1254
+ [6.5, 3.0],
1255
+ [9.0, 3.33],
1256
+ [13, 6]
1257
+ ], order: agg_vectors, index: agg_index))
1258
+ end
1259
+
1260
+ it "creates row and vector index as per (single) index and (double) vector args" do
1261
+ agg_vectors = Daru::MultiIndex.new(
1262
+ [
1263
+ [:d, :one, :large],
1264
+ [:d, :one, :small],
1265
+ [:d, :two, :large],
1266
+ [:d, :two, :small],
1267
+ [:e, :one, :large],
1268
+ [:e, :one, :small],
1269
+ [:e, :two, :large],
1270
+ [:e, :two, :small]
1271
+ ]
1272
+ )
1273
+
1274
+ agg_index = Daru::MultiIndex.new(
1275
+ [
1276
+ [:bar],
1277
+ [:foo]
1278
+ ]
1279
+ )
1280
+
1281
+ expect(@df.pivot_table(index: [:a], vectors: [:b, :c])).to eq(Daru::DataFrame.new(
1282
+ [
1283
+ [4.0,2.0],
1284
+ [5.0,1.0],
1285
+ [6.0,nil],
1286
+ [7.0,3.0],
1287
+ [8.0,4.0],
1288
+ [10.0,2.0],
1289
+ [12.0,nil],
1290
+ [14.0,6.0]
1291
+ ], order: agg_vectors, index: agg_index
1292
+ ))
1293
+ end
1294
+
1295
+ it "creates row and vector index with (double) index and (double) vector args", focus: true do
1296
+ agg_index = Daru::MultiIndex.new([
1297
+ [:bar, 4],
1298
+ [:bar, 5],
1299
+ [:bar, 6],
1300
+ [:bar, 7],
1301
+ [:foo, 1],
1302
+ [:foo, 2],
1303
+ [:foo, 3]
1304
+ ])
1305
+
1306
+ agg_vectors = Daru::MultiIndex.new([
1307
+ [:e, :one, :large],
1308
+ [:e, :one, :small],
1309
+ [:e, :two, :large],
1310
+ [:e, :two, :small]
1311
+ ])
1312
+
1313
+ expect(@df.pivot_table(index: [:a, :d], vectors: [:b, :c])).to eq(
1314
+ Daru::DataFrame.new(
1315
+ [
1316
+ [8 ,nil,nil,nil,nil, 4,nil],
1317
+ [nil, 10,nil,nil, 2,nil,nil],
1318
+ [nil,nil, 12,nil,nil,nil,nil],
1319
+ [nil,nil,nil, 14,nil,nil, 6],
1320
+ ], index: agg_index, order: agg_vectors)
1321
+ )
1322
+ end
1323
+
1324
+ it "only aggregates over the vector specified in the values argument" do
1325
+ agg_vectors = Daru::MultiIndex.new(
1326
+ [
1327
+ [:e, :one, :large],
1328
+ [:e, :one, :small],
1329
+ [:e, :two, :large],
1330
+ [:e, :two, :small]
1331
+ ]
1332
+ )
1333
+ agg_index = Daru::MultiIndex.new(
1334
+ [
1335
+ [:bar],
1336
+ [:foo]
1337
+ ]
1338
+ )
1339
+ expect(@df.pivot_table(index: [:a], vectors: [:b, :c], values: :e)).to eq(
1340
+ Daru::DataFrame.new(
1341
+ [
1342
+ [8, 4],
1343
+ [10, 2],
1344
+ [12,nil],
1345
+ [14, 6]
1346
+ ], order: agg_vectors, index: agg_index
1347
+ )
1348
+ )
1349
+ end
1350
+
1351
+ it "overrides default aggregate function to aggregate over sum" do
1352
+ agg_vectors = Daru::MultiIndex.new(
1353
+ [
1354
+ [:e, :one, :large],
1355
+ [:e, :one, :small],
1356
+ [:e, :two, :large],
1357
+ [:e, :two, :small]
1358
+ ]
1359
+ )
1360
+ agg_index = Daru::MultiIndex.new(
1361
+ [
1362
+ [:bar],
1363
+ [:foo]
1364
+ ]
1365
+ )
1366
+ expect(@df.pivot_table(index: [:a], vectors: [:b, :c], values: :e, agg: :sum)).to eq(
1367
+ Daru::DataFrame.new(
1368
+ [
1369
+ [8, 8],
1370
+ [10, 2],
1371
+ [12,nil],
1372
+ [14, 12]
1373
+ ], order: agg_vectors, index: agg_index
1374
+ )
1375
+ )
1376
+ end
1377
+
1378
+ it "raises error if no non-numeric vectors are present" do
1379
+ df = Daru::DataFrame.new({a: ['a', 'b', 'c'], b: ['b', 'e', 'd']})
1380
+ expect {
1381
+ df.pivot_table(index: [:a])
1382
+ }.to raise_error
1383
+ end
1384
+
1385
+ it "raises error if atleast a row index is not specified" do
1386
+ expect {
1387
+ @df.pivot_table
1388
+ }.to raise_error
1389
+ end
1390
+ end
1391
+
1392
+ context "#shape" do
1393
+ it "returns an array containing number of rows and columns" do
1394
+ expect(@data_frame.shape).to eq([5,3])
1395
+ end
634
1396
  end
635
1397
  end if mri?