daru 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +0 -0
  3. data/Gemfile +0 -1
  4. data/History.txt +35 -0
  5. data/README.md +178 -198
  6. data/daru.gemspec +5 -7
  7. data/lib/daru.rb +10 -2
  8. data/lib/daru/accessors/array_wrapper.rb +36 -198
  9. data/lib/daru/accessors/nmatrix_wrapper.rb +60 -209
  10. data/lib/daru/core/group_by.rb +183 -0
  11. data/lib/daru/dataframe.rb +615 -167
  12. data/lib/daru/index.rb +17 -16
  13. data/lib/daru/io/io.rb +5 -12
  14. data/lib/daru/maths/arithmetic/dataframe.rb +72 -8
  15. data/lib/daru/maths/arithmetic/vector.rb +19 -6
  16. data/lib/daru/maths/statistics/dataframe.rb +103 -2
  17. data/lib/daru/maths/statistics/vector.rb +102 -61
  18. data/lib/daru/monkeys.rb +8 -0
  19. data/lib/daru/multi_index.rb +199 -0
  20. data/lib/daru/plotting/dataframe.rb +24 -24
  21. data/lib/daru/plotting/vector.rb +14 -15
  22. data/lib/daru/vector.rb +402 -98
  23. data/lib/version.rb +1 -1
  24. data/notebooks/grouping_splitting_pivots.ipynb +529 -0
  25. data/notebooks/intro_with_music_data_.ipynb +104 -119
  26. data/spec/accessors/wrappers_spec.rb +36 -0
  27. data/spec/core/group_by_spec.rb +331 -0
  28. data/spec/dataframe_spec.rb +1237 -475
  29. data/spec/fixtures/sales-funnel.csv +18 -0
  30. data/spec/index_spec.rb +10 -21
  31. data/spec/io/io_spec.rb +4 -14
  32. data/spec/math/arithmetic/dataframe_spec.rb +66 -0
  33. data/spec/math/arithmetic/vector_spec.rb +45 -4
  34. data/spec/math/statistics/dataframe_spec.rb +91 -1
  35. data/spec/math/statistics/vector_spec.rb +32 -6
  36. data/spec/monkeys_spec.rb +10 -1
  37. data/spec/multi_index_spec.rb +216 -0
  38. data/spec/spec_helper.rb +1 -0
  39. data/spec/vector_spec.rb +505 -57
  40. metadata +21 -15
@@ -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?