daru 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.build.sh +6 -6
  3. data/.gitignore +2 -0
  4. data/CONTRIBUTING.md +7 -3
  5. data/History.md +36 -0
  6. data/README.md +21 -13
  7. data/Rakefile +16 -1
  8. data/benchmarks/TradeoffData.csv +65 -0
  9. data/benchmarks/dataframe_creation.rb +39 -0
  10. data/benchmarks/group_by.rb +32 -0
  11. data/benchmarks/row_access.rb +41 -0
  12. data/benchmarks/row_assign.rb +36 -0
  13. data/benchmarks/sorting.rb +44 -0
  14. data/benchmarks/vector_access.rb +31 -0
  15. data/benchmarks/vector_assign.rb +42 -0
  16. data/benchmarks/where_clause.rb +48 -0
  17. data/benchmarks/where_vs_filter.rb +28 -0
  18. data/daru.gemspec +29 -5
  19. data/lib/daru.rb +30 -1
  20. data/lib/daru/accessors/array_wrapper.rb +2 -2
  21. data/lib/daru/accessors/nmatrix_wrapper.rb +6 -6
  22. data/lib/daru/core/group_by.rb +112 -31
  23. data/lib/daru/core/merge.rb +170 -0
  24. data/lib/daru/core/query.rb +95 -0
  25. data/lib/daru/dataframe.rb +335 -223
  26. data/lib/daru/date_time/index.rb +550 -0
  27. data/lib/daru/date_time/offsets.rb +397 -0
  28. data/lib/daru/index.rb +266 -54
  29. data/lib/daru/io/io.rb +1 -2
  30. data/lib/daru/maths/arithmetic/dataframe.rb +2 -2
  31. data/lib/daru/maths/arithmetic/vector.rb +2 -2
  32. data/lib/daru/maths/statistics/dataframe.rb +58 -8
  33. data/lib/daru/maths/statistics/vector.rb +229 -0
  34. data/lib/daru/vector.rb +230 -80
  35. data/lib/daru/version.rb +1 -1
  36. data/spec/core/group_by_spec.rb +16 -16
  37. data/spec/core/merge_spec.rb +52 -0
  38. data/spec/core/query_spec.rb +171 -0
  39. data/spec/dataframe_spec.rb +278 -280
  40. data/spec/date_time/data_spec.rb +199 -0
  41. data/spec/date_time/index_spec.rb +433 -0
  42. data/spec/date_time/offsets_spec.rb +371 -0
  43. data/spec/fixtures/stock_data.csv +500 -0
  44. data/spec/index_spec.rb +317 -11
  45. data/spec/io/io_spec.rb +18 -17
  46. data/spec/math/arithmetic/dataframe_spec.rb +3 -3
  47. data/spec/math/statistics/dataframe_spec.rb +39 -1
  48. data/spec/math/statistics/vector_spec.rb +163 -1
  49. data/spec/monkeys_spec.rb +4 -0
  50. data/spec/spec_helper.rb +3 -0
  51. data/spec/vector_spec.rb +125 -60
  52. metadata +71 -14
  53. data/lib/daru/accessors/dataframe_by_vector.rb +0 -17
  54. data/lib/daru/multi_index.rb +0 -216
  55. data/spec/multi_index_spec.rb +0 -216
@@ -1,3 +1,3 @@
1
1
  module Daru
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -13,23 +13,23 @@ describe Daru::Core::GroupBy do
13
13
  @dl_group = @df.group_by([:a, :b])
14
14
  @tl_group = @df.group_by([:a,:b,:c])
15
15
 
16
- @sl_index = Daru::Index.new([:bar, :foo])
17
- @dl_multi_index = Daru::MultiIndex.new([
18
- [:bar, :one],
19
- [:bar, :three],
20
- [:bar, :two],
21
- [:foo, :one],
22
- [:foo, :three],
23
- [:foo, :two]
16
+ @sl_index = Daru::Index.new(['bar', 'foo'])
17
+ @dl_multi_index = Daru::MultiIndex.from_tuples([
18
+ ['bar', 'one'],
19
+ ['bar', 'three'],
20
+ ['bar', 'two'],
21
+ ['foo', 'one'],
22
+ ['foo', 'three'],
23
+ ['foo', 'two']
24
24
  ])
25
- @tl_multi_index = Daru::MultiIndex.new([
26
- [:bar, :one , 2],
27
- [:bar, :three, 1],
28
- [:bar, :two , 6],
29
- [:foo, :one , 1],
30
- [:foo, :one , 3],
31
- [:foo, :three, 8],
32
- [:foo, :two , 3]
25
+ @tl_multi_index = Daru::MultiIndex.from_tuples([
26
+ ['bar', 'one' , 2],
27
+ ['bar', 'three', 1],
28
+ ['bar', 'two' , 6],
29
+ ['foo', 'one' , 1],
30
+ ['foo', 'one' , 3],
31
+ ['foo', 'three', 8],
32
+ ['foo', 'two' , 3]
33
33
  ])
34
34
  end
35
35
 
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daru::DataFrame do
4
+ context "#join" do
5
+ before do
6
+ @left = Daru::DataFrame.new({
7
+ :id => [1,2,3,4],
8
+ :name => ['Pirate', 'Monkey', 'Ninja', 'Spaghetti']
9
+ })
10
+ @right = Daru::DataFrame.new({
11
+ :id => [1,2,3,4],
12
+ :name => ['Rutabaga', 'Pirate', 'Darth Vader', 'Ninja']
13
+ })
14
+ end
15
+
16
+ it "performs an inner join of two dataframes" do
17
+ answer = Daru::DataFrame.new({
18
+ :id_1 => [1,3],
19
+ :name => ['Pirate', 'Ninja'],
20
+ :id_2 => [2,4]
21
+ }, order: [:id_1, :name, :id_2])
22
+ expect(@left.join(@right, how: :inner, on: [:name])).to eq(answer)
23
+ end
24
+
25
+ it "performs a full outer join" do
26
+ answer = Daru::DataFrame.new({
27
+ :id_1 => [1,2,3,4,nil,nil],
28
+ :name => ['Pirate', 'Monkey', 'Ninja', 'Spaghetti','Rutabaga', 'Darth Vader'],
29
+ :id_2 => [2,nil,4,nil,1,3]
30
+ }, order: [:id_1, :name, :id_2])
31
+ expect(@left.join(@right, how: :outer, on: [:name])).to eq(answer)
32
+ end
33
+
34
+ it "performs a left outer join", focus: true do
35
+ answer = Daru::DataFrame.new({
36
+ :id_1 => [1,2,3,4],
37
+ :name => ['Pirate', 'Monkey', 'Ninja', 'Spaghetti'],
38
+ :id_2 => [2,nil,4,nil]
39
+ }, order: [:id_1, :name, :id_2])
40
+ expect(@left.join(@right, how: :left, on: [:name])).to eq(answer)
41
+ end
42
+
43
+ it "performs a right outer join" do
44
+ answer = Daru::DataFrame.new({
45
+ :id_1 => [nil,1,nil,3],
46
+ :name => ['Rutabaga','Pirate', 'Darth Vader', 'Ninja'],
47
+ :id_2 => [1,2,3,4]
48
+ }, order: [:id_1, :name, :id_2])
49
+ expect(@left.join(@right, how: :right, on: [:name])).to eq(answer)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,171 @@
1
+ require 'spec_helper'
2
+
3
+ describe Daru::Core::Query::BoolArray do
4
+ before do
5
+ @klass = Daru::Core::Query::BoolArray
6
+ @left = @klass.new([true, true, true, false, false, true])
7
+ @right = @klass.new([false, false, false, false, true, false])
8
+ end
9
+
10
+ context "#&" do
11
+ it "computes and logic of each element in the array" do
12
+ expect(@left & @right).to eq(
13
+ @klass.new([false, false, false, false, false, false]))
14
+ end
15
+ end
16
+
17
+ context "#|" do
18
+ it "computes or logic of each element in arrays" do
19
+ expect(@left | @right).to eq(
20
+ @klass.new([true, true, true, false, true, true]))
21
+ end
22
+ end
23
+
24
+ context "#!" do
25
+ it "computes not logic of each element" do
26
+ expect(!@left).to eq(
27
+ @klass.new([false, false, false, true, true, false])
28
+ )
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "Arel-like syntax" do
34
+ describe "comparison operators" do
35
+ describe Daru::Vector do
36
+ before do
37
+ @vector = Daru::Vector.new([23,51,1214,352,32,11])
38
+ @comparator = Daru::Vector.new([45,22,1214,55,32,9])
39
+ @klass = Daru::Core::Query::BoolArray
40
+ end
41
+
42
+ context "#eq" do
43
+ it "accepts scalar value" do
44
+ expect(@vector.eq(352)).to eq(
45
+ @klass.new([false,false,false,true,false,false]))
46
+ end
47
+
48
+ it "accepts vector and compares corrensponding elements" do
49
+ expect(@vector.eq(@comparator)).to eq(
50
+ @klass.new([false,false,true,false,true,false]))
51
+ end
52
+ end
53
+
54
+ context "#not_eq" do
55
+ it "accepts scalar value" do
56
+ expect(@vector.not_eq(51)).to eq(
57
+ @klass.new([true, false, true, true, true, true]))
58
+ end
59
+
60
+ it "accepts vector and compares corrensponding elements" do
61
+ expect(@vector.not_eq(@comparator)).to eq(
62
+ @klass.new([true, true, false, true, false, true]))
63
+ end
64
+ end
65
+
66
+ context "#lt" do
67
+ it "accepts scalar value" do
68
+ expect(@vector.lt(51)).to eq(
69
+ @klass.new([true, false, false, false, true, true]))
70
+ end
71
+
72
+ it "accepts vector and compares corrensponding elements" do
73
+ expect(@vector.lt(@comparator)).to eq(
74
+ @klass.new([true,false,false,false,false,false]))
75
+ end
76
+ end
77
+
78
+ context "#lteq" do
79
+ it "accepts scalar value" do
80
+ expect(@vector.lteq(51)).to eq(
81
+ @klass.new([true, true, false, false, true, true]))
82
+ end
83
+
84
+ it "accepts vector and compares corrensponding elements" do
85
+ expect(@vector.lteq(@comparator)).to eq(
86
+ @klass.new([true,false,true,false,true,false]))
87
+ end
88
+ end
89
+
90
+ context "#mt" do
91
+ it "accepts scalar value" do
92
+ expect(@vector.mt(51)).to eq(
93
+ @klass.new([false, false, true, true, false, false]))
94
+ end
95
+
96
+ it "accepts vector and compares corrensponding elements" do
97
+ expect(@vector.mt(@comparator)).to eq(
98
+ @klass.new([false,true,false,true,false,true]))
99
+ end
100
+ end
101
+
102
+ context "#mteq" do
103
+ it "accepts scalar value" do
104
+ expect(@vector.mteq(51)).to eq(
105
+ @klass.new([false, true, true, true, false, false]))
106
+ end
107
+
108
+ it "accepts vector and compares corrensponding elements" do
109
+ expect(@vector.mteq(@comparator)).to eq(
110
+ @klass.new([false,true,true,true,true,true]))
111
+ end
112
+ end
113
+
114
+ context "#in" do
115
+ it "checks if any of elements in the arg are present in the vector" do
116
+ expect(@vector.in([23,55,1,33,32])).to eq(
117
+ @klass.new([true, false, false, false, true, false]))
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ describe "where clause" do
124
+ context Daru::DataFrame do
125
+ before do
126
+ @df = Daru::DataFrame.new({
127
+ number: [1,2,3,4,5,6],
128
+ sym: [:one, :two, :three, :four, :five, :six],
129
+ names: ['sameer', 'john', 'james', 'omisha', 'priyanka', 'shravan']
130
+ })
131
+ end
132
+
133
+ it "accepts simple single eq statement" do
134
+ answer = Daru::DataFrame.new({
135
+ number: [4],
136
+ sym: [:four],
137
+ names: ['omisha']
138
+ }, index: Daru::Index.new([3])
139
+ )
140
+ expect(@df.where(@df[:number].eq(4))).to eq(answer)
141
+ end
142
+
143
+ it "accepts somewhat complex comparison operator chaining" do
144
+ answer = Daru::DataFrame.new({
145
+ number: [3,4],
146
+ sym: [:three, :four],
147
+ names: ['james', 'omisha']
148
+ }, index: Daru::Index.new([2,3]))
149
+ expect(
150
+ @df.where (@df[:names].eq('james') | @df[:sym].eq(:four))
151
+ ).to eq(answer)
152
+ end
153
+ end
154
+
155
+ context Daru::Vector do
156
+ before do
157
+ @vector = Daru::Vector.new([2,5,1,22,51,4])
158
+ end
159
+
160
+ it "accepts a simple single statement" do
161
+ expect(@vector.where(@vector.lt(10))).to eq(
162
+ Daru::Vector.new([2,5,1,4], index: Daru::Index.new([0,1,2,5])))
163
+ end
164
+
165
+ it "accepts somewhat complex operator chaining" do
166
+ expect(@vector.where((@vector.lt(6) | @vector.eq(51)))).to eq(
167
+ Daru::Vector.new([2,5,1,51,4], index: Daru::Index.new([0,1,2,4,5])))
168
+ end
169
+ end
170
+ end
171
+ end
@@ -20,12 +20,12 @@ describe Daru::DataFrame do
20
20
  [:c,:two,:foo],
21
21
  [:c,:two,:bar]
22
22
  ]
23
- @multi_index = Daru::MultiIndex.new(tuples)
23
+ @multi_index = Daru::MultiIndex.from_tuples(tuples)
24
24
 
25
25
  @vector_arry1 = [11,12,13,14,11,12,13,14,11,12,13,14]
26
26
  @vector_arry2 = [1,2,3,4,1,2,3,4,1,2,3,4]
27
27
 
28
- @order_mi = Daru::MultiIndex.new([
28
+ @order_mi = Daru::MultiIndex.from_tuples([
29
29
  [:a,:one,:bar],
30
30
  [:a,:two,:baz],
31
31
  [:b,:two,:foo],
@@ -54,7 +54,7 @@ describe Daru::DataFrame do
54
54
 
55
55
  expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
56
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])
57
+ expect(df[:a]) .to eq(Daru::Vector.new [1,1,1,1])
58
58
  end
59
59
 
60
60
  it "creates a DataFrame from Vector rows" do
@@ -64,17 +64,18 @@ describe Daru::DataFrame do
64
64
 
65
65
  expect(df.index) .to eq(Daru::Index.new [0,1,2,3])
66
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])
67
+ expect(df[:a]) .to eq(Daru::Vector.new [1,1,1,1])
68
68
  end
69
69
  end
70
70
 
71
71
  context Daru::MultiIndex do
72
72
  it "creates a DataFrame from rows" do
73
- df = Daru::DataFrame.rows(@rows*3, index: @multi_index, order: [:a,:b,:c,:d,:e])
73
+ df = Daru::DataFrame.rows(
74
+ @rows*3, index: @multi_index, order: [:a,:b,:c,:d,:e])
74
75
 
75
76
  expect(df.index) .to eq(@multi_index)
76
77
  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
+ expect(df[:a]).to eq(Daru::Vector.new([1]*12, index: @multi_index))
78
79
  end
79
80
 
80
81
  it "crates a DataFrame from rows (MultiIndex order)" do
@@ -84,7 +85,7 @@ describe Daru::DataFrame do
84
85
  [13, 3, 13, 3],
85
86
  [14, 4, 14, 4]
86
87
  ]
87
- index = Daru::MultiIndex.new([
88
+ index = Daru::MultiIndex.from_tuples([
88
89
  [:one,:bar],
89
90
  [:one,:baz],
90
91
  [:two,:foo],
@@ -94,7 +95,7 @@ describe Daru::DataFrame do
94
95
  df = Daru::DataFrame.rows(rows, index: index, order: @order_mi)
95
96
  expect(df.index) .to eq(index)
96
97
  expect(df.vectors).to eq(@order_mi)
97
- expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new([11,12,13,14],
98
+ expect(df[:a, :one, :bar]).to eq(Daru::Vector.new([11,12,13,14],
98
99
  index: index))
99
100
  end
100
101
 
@@ -106,7 +107,7 @@ describe Daru::DataFrame do
106
107
 
107
108
  expect(df.index).to eq(Daru::Index.new(Array.new(rows.size) { |i| i }))
108
109
  expect(df.vectors).to eq(@multi_index)
109
- expect(df.vector[:a,:one,:bar]).to eq(Daru::Vector.new([1]*12))
110
+ expect(df[:a,:one,:bar]).to eq(Daru::Vector.new([1]*12))
110
111
  end
111
112
  end
112
113
  end
@@ -275,7 +276,7 @@ describe Daru::DataFrame do
275
276
  expect(df[:c].object_id).to eq(c.object_id)
276
277
  end
277
278
 
278
- it "allows creation of empty dataframe with only order", focus: true do
279
+ it "allows creation of empty dataframe with only order" do
279
280
  df = Daru::DataFrame.new({}, order: [:a, :b, :c])
280
281
  df[:a] = Daru::Vector.new([1,2,3,4,5,6])
281
282
 
@@ -317,7 +318,7 @@ describe Daru::DataFrame do
317
318
  df = Daru::DataFrame.new({}, order: @order_mi)
318
319
 
319
320
  expect(df.vectors).to eq(@order_mi)
320
- expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new([]))
321
+ expect(df[:a, :one, :bar]).to eq(Daru::Vector.new([]))
321
322
  end
322
323
 
323
324
  it "creates from Hash" do
@@ -330,7 +331,7 @@ describe Daru::DataFrame do
330
331
 
331
332
  expect(df.index) .to eq(@multi_index)
332
333
  expect(df.vectors) .to eq(@order_mi)
333
- expect(df.vector[:a,:one,:bar]).to eq(Daru::Vector.new(@vector_arry1,
334
+ expect(df[:a,:one,:bar]).to eq(Daru::Vector.new(@vector_arry1,
334
335
  index: @multi_index))
335
336
  end
336
337
 
@@ -344,7 +345,7 @@ describe Daru::DataFrame do
344
345
 
345
346
  expect(df.index) .to eq(@multi_index)
346
347
  expect(df.vectors).to eq(@order_mi)
347
- expect(df.vector[:a, :one, :bar]).to eq(Daru::Vector.new(@vector_arry1,
348
+ expect(df[:a, :one, :bar]).to eq(Daru::Vector.new(@vector_arry1,
348
349
  index: @multi_index))
349
350
  end
350
351
 
@@ -358,19 +359,19 @@ describe Daru::DataFrame do
358
359
  it "aligns MultiIndexes properly" do
359
360
  pending
360
361
  mi_a = @order_mi
361
- mi_b = Daru::MultiIndex.new([
362
+ mi_b = Daru::MultiIndex.from_tuples([
362
363
  [:b,:one,:foo],
363
364
  [:a,:one,:bar],
364
365
  [:b,:two,:foo],
365
366
  [:a,:one,:baz]
366
367
  ])
367
- mi_sorted = Daru::MultiIndex.new([
368
+ mi_sorted = Daru::MultiIndex.from_tuples([
368
369
  [:a, :one, :bar],
369
370
  [:a, :one, :baz],
370
371
  [:b, :one, :foo],
371
372
  [:b, :two, :foo]
372
373
  ])
373
- order = Daru::MultiIndex.new([
374
+ order = Daru::MultiIndex.from_tuples([
374
375
  [:pee, :que],
375
376
  [:pee, :poo]
376
377
  ])
@@ -394,7 +395,7 @@ describe Daru::DataFrame do
394
395
  end
395
396
  end
396
397
 
397
- context "#[:vector]" do
398
+ context "#[]" do
398
399
  context Daru::Index do
399
400
  before :each do
400
401
  @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
@@ -403,7 +404,7 @@ describe Daru::DataFrame do
403
404
  end
404
405
 
405
406
  it "returns a Vector" do
406
- expect(@df[:a, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
407
+ expect(@df[:a]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
407
408
  end
408
409
 
409
410
  it "returns a Vector by default" do
@@ -415,11 +416,11 @@ describe Daru::DataFrame do
415
416
  temp = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
416
417
  order: [:a, :b], index: [:one, :two, :three, :four, :five])
417
418
 
418
- expect(@df[:a, :b, :vector]).to eq(temp)
419
+ expect(@df[:a, :b]).to eq(temp)
419
420
  end
420
421
 
421
422
  it "accesses vector with Integer index" do
422
- expect(@df[0, :vector]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
423
+ expect(@df[0]).to eq([1,2,3,4,5].dv(:a, [:one, :two, :three, :four, :five]))
423
424
  end
424
425
 
425
426
  it "returns a subset of DataFrame when specified range" do
@@ -432,41 +433,35 @@ describe Daru::DataFrame do
432
433
  end
433
434
 
434
435
  context Daru::MultiIndex do
435
- # See #vector
436
- end
437
- end
438
-
439
- context "#[:row]" do
440
- context Daru::Index do
441
- before :each do
442
- @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
443
- c: [11,22,33,44,55]},
444
- order: [:a, :b, :c],
445
- index: [:one, :two, :three, :four, :five])
436
+ it "accesses vector with an integer index" do
437
+ expect(@df_mi[0]).to eq(
438
+ Daru::Vector.new(@vector_arry1, index: @multi_index))
446
439
  end
447
440
 
448
- it "returns a row with the given index" do
449
- expect(@df[:one, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
441
+ it "returns a vector when specifying full tuple" do
442
+ expect(@df_mi[:a, :one, :bar]).to eq(
443
+ Daru::Vector.new(@vector_arry1, index: @multi_index))
450
444
  end
451
445
 
452
- it "returns a row with given Integer index" do
453
- expect(@df[0, :row]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
446
+ it "returns DataFrame when specified first layer of MultiIndex" do
447
+ sub_order = Daru::MultiIndex.from_tuples([
448
+ [:one, :bar],
449
+ [:two, :baz]
450
+ ])
451
+ expect(@df_mi[:a]).to eq(Daru::DataFrame.new([
452
+ @vector_arry1,
453
+ @vector_arry2
454
+ ], index: @multi_index, order: sub_order))
454
455
  end
455
456
 
456
- it "returns a row with given Integer index for default index-less DataFrame" do
457
- df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
458
- c: [11,22,33,44,55]}, order: [:a, :b, :c])
459
-
460
- expect(df[0, :row]).to eq([1,11,11].dv(nil, [:a, :b, :c]))
457
+ it "returns a Vector if the last level of MultiIndex is tracked" do
458
+ expect(@df_mi[:a, :one]).to eq(
459
+ Daru::Vector.new(@vector_arry1, index: @multi_index))
461
460
  end
462
461
  end
463
-
464
- context Daru::MultiIndex do
465
- # See #row
466
- end
467
462
  end
468
463
 
469
- context "#[:vector]=" do
464
+ context "#[]=" do
470
465
  context Daru::Index do
471
466
  before :each do
472
467
  @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
@@ -474,46 +469,55 @@ describe Daru::DataFrame do
474
469
  index: [:one, :two, :three, :four, :five])
475
470
  end
476
471
 
472
+ it "assigns directly with the []= operator" do
473
+ @data_frame[:a] = [100,200,300,400,500]
474
+ expect(@data_frame).to eq(Daru::DataFrame.new({
475
+ b: [11,12,13,14,15],
476
+ a: [100,200,300,400,500],
477
+ c: [11,22,33,44,55]}, order: [:a, :b, :c],
478
+ index: [:one, :two, :three, :four, :five]))
479
+ end
480
+
477
481
  it "appends an Array as a Daru::Vector" do
478
- @df[:d, :vector] = [69,99,108,85,49]
482
+ @df[:d] = [69,99,108,85,49]
479
483
 
480
484
  expect(@df.d.class).to eq(Daru::Vector)
481
485
  end
482
486
 
483
487
  it "replaces an already present vector" do
484
- @df[:a, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
488
+ @df[:a] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
485
489
 
486
490
  expect(@df.a).to eq([69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five]))
487
491
  end
488
492
 
489
493
  it "appends a new vector to the DataFrame" do
490
- @df[:woo, :vector] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
494
+ @df[:woo] = [69,99,108,85,49].dv(nil, [:one, :two, :three, :four, :five])
491
495
 
492
496
  expect(@df.vectors).to eq([:a, :b, :c, :woo].to_index)
493
497
  end
494
498
 
495
499
  it "creates an index for the new vector if not specified" do
496
- @df[:woo, :vector] = [69,99,108,85,49]
500
+ @df[:woo] = [69,99,108,85,49]
497
501
 
498
502
  expect(@df.woo.index).to eq([:one, :two, :three, :four, :five].to_index)
499
503
  end
500
504
 
501
505
  it "matches index of vector to be inserted with the DataFrame index" do
502
- @df[:shankar, :vector] = [69,99,108,85,49].dv(:shankar, [:two, :one, :three, :five, :four])
506
+ @df[:shankar] = [69,99,108,85,49].dv(:shankar, [:two, :one, :three, :five, :four])
503
507
 
504
508
  expect(@df.shankar).to eq([99,69,108,49,85].dv(:shankar,
505
509
  [:one, :two, :three, :four, :five]))
506
510
  end
507
511
 
508
512
  it "matches index of vector to be inserted, inserting nils where no match found" do
509
- @df.vector[:shankar] = [1,2,3].dv(:shankar, [:one, :james, :hetfield])
513
+ @df[:shankar] = [1,2,3].dv(:shankar, [:one, :james, :hetfield])
510
514
 
511
515
  expect(@df.shankar).to eq([1,nil,nil,nil,nil].dv(:shankar, [:one, :two, :three, :four, :five]))
512
516
  end
513
517
 
514
518
  it "raises error for Array assignment of wrong length" do
515
519
  expect{
516
- @df.vector[:shiva] = [1,2,3]
520
+ @df[:shiva] = [1,2,3]
517
521
  }.to raise_error
518
522
  end
519
523
 
@@ -521,23 +525,6 @@ describe Daru::DataFrame do
521
525
  # TODO
522
526
  end
523
527
  end
524
-
525
- context Daru::MultiIndex do
526
- pending
527
- end
528
- end
529
-
530
- context "#[]=" do
531
- context Daru::Index do
532
- it "assigns directly with the []= operator" do
533
- @data_frame[:a] = [100,200,300,400,500]
534
- expect(@data_frame).to eq(Daru::DataFrame.new({
535
- b: [11,12,13,14,15],
536
- a: [100,200,300,400,500],
537
- c: [11,22,33,44,55]}, order: [:a, :b, :c],
538
- index: [:one, :two, :three, :four, :five]))
539
- end
540
- end
541
528
 
542
529
  context Daru::MultiIndex do
543
530
  it "raises error when incomplete index specified but index is absent" do
@@ -547,7 +534,6 @@ describe Daru::DataFrame do
547
534
  end
548
535
 
549
536
  it "assigns all sub-indexes when a top level index is specified" do
550
- pending
551
537
  @df_mi[:a] = [100,200,300,400,100,200,300,400,100,200,300,400]
552
538
 
553
539
  expect(@df_mi).to eq(Daru::DataFrame.new([
@@ -558,8 +544,7 @@ describe Daru::DataFrame do
558
544
  end
559
545
 
560
546
  it "creates a new vector when full index specfied" do
561
- pending
562
- order = Daru::MultiIndex.new([
547
+ order = Daru::MultiIndex.from_tuples([
563
548
  [:a,:one,:bar],
564
549
  [:a,:two,:baz],
565
550
  [:b,:two,:foo],
@@ -579,7 +564,7 @@ describe Daru::DataFrame do
579
564
  end
580
565
  end
581
566
 
582
- context "#[:row]=" do
567
+ context "#row[]=" do
583
568
  context Daru::Index do
584
569
  before :each do
585
570
  @df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
@@ -590,33 +575,39 @@ describe Daru::DataFrame do
590
575
  it "assigns specified row when Array" do
591
576
  @df.row[:one] = [49, 99, 59]
592
577
 
593
- expect(@df[:one, :row]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
594
- expect(@df[:one, :row].index).to eq([:a, :b, :c].to_index)
595
- expect(@df[:one, :row].name) .to eq(:one)
578
+ expect(@df.row[:one]) .to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
579
+ expect(@df.row[:one].index).to eq([:a, :b, :c].to_index)
580
+ expect(@df.row[:one].name) .to eq(:one)
596
581
  end
597
582
 
598
583
  it "assigns specified row when DV" do
599
- @df[:one, :row] = [49, 99, 59].dv(nil, [:a, :b, :c])
584
+ @df.row[:one] = [49, 99, 59].dv(nil, [:a, :b, :c])
600
585
 
601
- expect(@df[:one, :row]).to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
586
+ expect(@df.row[:one]).to eq([49, 99, 59].dv(:one, [:a, :b, :c]))
587
+ end
588
+
589
+ it "assigns correct elements when Vector of different index" do
590
+ @df.row[:one] = Daru::Vector.new([44,62,11], index: [:b,:f,:a])
591
+
592
+ expect(@df.row[:one]).to eq(Daru::Vector.new([11,44,nil], index: [:a,:b,:c]))
602
593
  end
603
594
 
604
595
  it "creates a new row from an Array" do
605
596
  @df.row[:patekar] = [9,2,11]
606
597
 
607
- expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
598
+ expect(@df.row[:patekar]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
608
599
  end
609
600
 
610
601
  it "creates a new row from a DV" do
611
602
  @df.row[:patekar] = [9,2,11].dv(nil, [:a, :b, :c])
612
603
 
613
- expect(@df[:patekar, :row]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
604
+ expect(@df.row[:patekar]).to eq([9,2,11].dv(:patekar, [:a, :b, :c]))
614
605
  end
615
606
 
616
607
  it "creates a new row from numeric row index and named DV" do
617
608
  @df.row[2] = [9,2,11].dv(nil, [:a, :b, :c])
618
609
 
619
- expect(@df[2, :row]).to eq([9,2,11].dv(nil, [:a, :b, :c]))
610
+ expect(@df.row[2]).to eq([9,2,11].dv(nil, [:a, :b, :c]))
620
611
  end
621
612
 
622
613
  it "correctly aligns assigned DV by index" do
@@ -685,7 +676,22 @@ describe Daru::DataFrame do
685
676
  c: [11,22,33]}, order: [:a, :b, :c],
686
677
  index: [:one, :two, :three])
687
678
  )
688
- end
679
+ end
680
+
681
+ it "returns a row with the given index" do
682
+ expect(@df.row[:one]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
683
+ end
684
+
685
+ it "returns a row with given Integer index" do
686
+ expect(@df.row[0]).to eq([1,11,11].dv(:one, [:a, :b, :c]))
687
+ end
688
+
689
+ it "returns a row with given Integer index for default index-less DataFrame" do
690
+ df = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5],
691
+ c: [11,22,33,44,55]}, order: [:a, :b, :c])
692
+
693
+ expect(df.row[0]).to eq([1,11,11].dv(nil, [:a, :b, :c]))
694
+ end
689
695
  end
690
696
 
691
697
  context Daru::MultiIndex do
@@ -694,22 +700,16 @@ describe Daru::DataFrame do
694
700
  end
695
701
 
696
702
  it "returns a DataFrame when specifying numeric range" do
697
- sub_index = Daru::MultiIndex.new([
703
+ sub_index = Daru::MultiIndex.from_tuples([
698
704
  [:a,:one,:bar],
699
- [:a,:one,:baz],
700
- [:a,:two,:bar],
701
- [:a,:two,:baz],
702
- [:b,:one,:bar],
703
- [:b,:two,:bar],
704
- [:b,:two,:baz],
705
- [:b,:one,:foo]
705
+ [:a,:one,:baz]
706
706
  ])
707
707
 
708
708
  expect(@df_mi.row[0..1]).to eq(Daru::DataFrame.new([
709
- [11,12,13,14,11,12,13,14],
710
- [1,2,3,4,1,2,3,4],
711
- [11,12,13,14,11,12,13,14],
712
- [1,2,3,4,1,2,3,4]
709
+ [11,12],
710
+ [1,2],
711
+ [11,12],
712
+ [1,2]
713
713
  ], order: @order_mi, index: sub_index, name: :numeric_range))
714
714
  end
715
715
 
@@ -718,7 +718,7 @@ describe Daru::DataFrame do
718
718
  end
719
719
 
720
720
  it "returns DataFrame when specifying first layer of MultiIndex" do
721
- sub_index = Daru::MultiIndex.new([
721
+ sub_index = Daru::MultiIndex.from_tuples([
722
722
  [:one,:bar],
723
723
  [:one,:baz],
724
724
  [:two,:foo],
@@ -733,7 +733,7 @@ describe Daru::DataFrame do
733
733
  end
734
734
 
735
735
  it "returns DataFrame when specifying first and second layer of MultiIndex" do
736
- sub_index = Daru::MultiIndex.new([
736
+ sub_index = Daru::MultiIndex.from_tuples([
737
737
  [:bar],
738
738
  [:baz]
739
739
  ])
@@ -760,48 +760,6 @@ describe Daru::DataFrame do
760
760
  end
761
761
  end
762
762
 
763
- context "#vector" do
764
- context Daru::Index do
765
- it "appends an Array as a Daru::Vector" do
766
- @data_frame[:d, :vector] = [69,99,108,85,49]
767
-
768
- expect(@data_frame.d.class).to eq(Daru::Vector)
769
- end
770
- end
771
-
772
- context Daru::MultiIndex do
773
- it "accesses vector with an integer index" do
774
- expect(@df_mi.vector[0]).to eq(Daru::Vector.new(@vector_arry1,
775
- index: @multi_index))
776
- end
777
-
778
- it "returns a vector when specifying full tuple" do
779
- expect(@df_mi.vector[:a, :one, :bar]).to eq(Daru::Vector.new(@vector_arry1,
780
- index: @multi_index))
781
- end
782
-
783
- it "returns DataFrame when specified first layer of MultiIndex" do
784
- sub_order = Daru::MultiIndex.new([
785
- [:one, :bar],
786
- [:two, :baz]
787
- ])
788
- expect(@df_mi.vector[:a]).to eq(Daru::DataFrame.new([
789
- @vector_arry1,
790
- @vector_arry2
791
- ], index: @multi_index, order: sub_order))
792
- end
793
-
794
- it "returns DataFrame when specified first and second layer of MultiIndex" do
795
- sub_order = Daru::MultiIndex.new([
796
- [:bar]
797
- ])
798
- expect(@df_mi.vector[:a, :one]).to eq(Daru::DataFrame.new([
799
- @vector_arry1
800
- ], index: @multi_index, order: sub_order))
801
- end
802
- end
803
- end
804
-
805
763
  context "#==" do
806
764
  it "compares by vectors, index and values of a DataFrame (ignores name)" do
807
765
  a = Daru::DataFrame.new({b: [11,12,13,14,15], a: [1,2,3,4,5]},
@@ -824,7 +782,7 @@ describe Daru::DataFrame do
824
782
  expect(clo.index.object_id) .not_to eq(@data_frame.object_id)
825
783
 
826
784
  @data_frame.each_vector_with_index do |vector, index|
827
- expect(vector.object_id).not_to eq(clo.vector[index].object_id)
785
+ expect(vector.object_id).not_to eq(clo[index].object_id)
828
786
  end
829
787
  end
830
788
  end
@@ -1092,18 +1050,14 @@ describe Daru::DataFrame do
1092
1050
  index: [:one, :two, :three, :four, :five]))
1093
1051
  end
1094
1052
  end
1095
-
1096
- context Daru::MultiIndex do
1097
- pending
1098
- end
1099
1053
  end
1100
1054
 
1101
1055
  context "#delete_row" do
1102
1056
  it "deletes the specified row" do
1103
- @data_frame.delete_row :one
1057
+ @data_frame.delete_row :three
1104
1058
 
1105
- expect(@data_frame).to eq(Daru::DataFrame.new({b: [12,13,14,15], a: [2,3,4,5],
1106
- c: [22,33,44,55]}, order: [:a, :b, :c], index: [:two, :three, :four, :five]))
1059
+ expect(@data_frame).to eq(Daru::DataFrame.new({b: [11,12,14,15], a: [1,2,4,5],
1060
+ c: [11,22,44,55]}, order: [:a, :b, :c], index: [:one, :two, :four, :five]))
1107
1061
  end
1108
1062
  end
1109
1063
 
@@ -1161,10 +1115,6 @@ describe Daru::DataFrame do
1161
1115
  expect(a).to eq(Daru::DataFrame.new({a: [2], b: [3]}, order: [:a, :b], index: [1]))
1162
1116
  end
1163
1117
  end
1164
-
1165
- context Daru::MultiIndex do
1166
- pending
1167
- end
1168
1118
  end
1169
1119
 
1170
1120
  context "#filter_vectors" do
@@ -1179,10 +1129,6 @@ describe Daru::DataFrame do
1179
1129
  expect(a).to eq(Daru::DataFrame.new({a: [1,2,3]}))
1180
1130
  end
1181
1131
  end
1182
-
1183
- context Daru::MultiIndex do
1184
- pending
1185
- end
1186
1132
  end
1187
1133
 
1188
1134
  context "#to_a" do
@@ -1321,79 +1267,86 @@ describe Daru::DataFrame do
1321
1267
  @df_mi.sort([[:a,:one,:bar]])
1322
1268
  end
1323
1269
  end
1324
- end
1270
+ end
1325
1271
 
1326
- context "#reindex" do
1327
- it "sets a new sequential index for DF and its underlying vectors" do
1328
- a = @data_frame.reindex(:seq)
1272
+ context "#index=" do
1273
+ before :each do
1274
+ @df = Daru::DataFrame.new({
1275
+ a: [1,2,3,4,5],
1276
+ b: [11,22,33,44,55],
1277
+ c: %w(a b c d e)
1278
+ })
1279
+ end
1329
1280
 
1330
- expect(a).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
1331
- a: [1,2,3,4,5], c: [11,22,33,44,55]}, order: [:a, :b, :c]))
1332
- expect(a).to_not eq(@data_frame)
1281
+ it "simply reassigns the index" do
1282
+ @df.index = Daru::Index.new(['4','foo', :bar, 0, 23])
1283
+ expect(@df.row['foo']).to eq(Daru::Vector.new([2,22,'b'], index: [:a,:b,:c]))
1284
+ end
1333
1285
 
1334
- expect(a.a.index).to eq(Daru::Index.new(5))
1335
- expect(a.b.index).to eq(Daru::Index.new(5))
1336
- expect(a.c.index).to eq(Daru::Index.new(5))
1286
+ it "raises error for improper length index" do
1287
+ expect {
1288
+ @df.index = Daru::Index.new([1,2])
1289
+ }.to raise_error(ArgumentError)
1337
1290
  end
1291
+ end
1338
1292
 
1339
- it "sets a new index for the data frame and its underlying vectors" do
1340
- a = @data_frame.reindex([:a,:b,:c,:d,:e])
1293
+ context "#vectors=" do
1294
+ before :each do
1295
+ @df = Daru::DataFrame.new({
1296
+ a: [1,2,3,4,5],
1297
+ b: [11,22,33,44,55],
1298
+ c: %w(a b c d e)
1299
+ })
1300
+ end
1341
1301
 
1342
- expect(a).to eq(Daru::DataFrame.new(
1343
- {b: [11,12,13,14,15], a: [1,2,3,4,5], c: [11,22,33,44,55]},
1344
- order: [:a, :b, :c], index: [:a,:b,:c,:d,:e]))
1345
- expect(a).to_not eq(@data_frame)
1302
+ it "simply reassigns vectors" do
1303
+ @df.vectors = Daru::Index.new(['b',0,'m'])
1346
1304
 
1347
- expect(a.a.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1348
- expect(a.b.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1349
- expect(a.c.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1305
+ expect(@df.vectors).to eq(Daru::Index.new(['b',0,'m']))
1306
+ expect(@df['b']).to eq(Daru::Vector.new([1,2,3,4,5]))
1307
+ expect(@df[0]).to eq(Daru::Vector.new([11,22,33,44,55]))
1308
+ expect(@df['m']).to eq(Daru::Vector.new(%w(a b c d e)))
1350
1309
  end
1351
- end
1352
1310
 
1353
- context "#reindex!" do
1354
- context Daru::Index do
1355
- it "sets a new sequential index for DF and its underlying vectors" do
1356
- expect(@data_frame.reindex!(:seq)).to eq(Daru::DataFrame.new({b: [11,12,13,14,15],
1357
- a: [1,2,3,4,5], c: [11,22,33,44,55]}, order: [:a, :b, :c]))
1358
- expect(@data_frame.a.index).to eq(Daru::Index.new(5))
1359
- expect(@data_frame.b.index).to eq(Daru::Index.new(5))
1360
- expect(@data_frame.c.index).to eq(Daru::Index.new(5))
1361
- end
1362
-
1363
- it "sets a new index for the data frame and its underlying vectors" do
1364
- expect(@data_frame.reindex!([:a,:b,:c,:d,:e])).to eq(Daru::DataFrame.new(
1365
- {b: [11,12,13,14,15], a: [1,2,3,4,5], c: [11,22,33,44,55]},
1366
- order: [:a, :b, :c], index: [:a,:b,:c,:d,:e]))
1367
- expect(@data_frame.a.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1368
- expect(@data_frame.b.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1369
- expect(@data_frame.c.index).to eq(Daru::Index.new([:a,:b,:c,:d,:e]))
1370
- end
1311
+ it "raises error for improper length index" do
1312
+ expect {
1313
+ @df.vectors = Daru::Index.new([1,2,'3',4,'5'])
1314
+ }.to raise_error(ArgumentError)
1371
1315
  end
1372
-
1373
- context Daru::MultiIndex do
1374
- pending "feature manually tested. write tests"
1375
- end
1376
1316
  end
1377
1317
 
1378
- context "#reindex_vectors!" do
1379
- before :each do
1380
- @df = Daru::DataFrame.new({
1318
+ context "#reindex" do
1319
+ it "re indexes and aligns accordingly" do
1320
+ df = Daru::DataFrame.new({
1381
1321
  a: [1,2,3,4,5],
1382
1322
  b: [11,22,33,44,55],
1383
1323
  c: %w(a b c d e)
1384
1324
  })
1325
+
1326
+ ans = df.reindex(Daru::Index.new([1,3,0,8,2]))
1327
+ expect(ans).to eq(Daru::DataFrame.new({
1328
+ a: [2,4,1,nil,3],
1329
+ b: [22,44,11,nil,33],
1330
+ c: ['b','d','a',nil,'c']
1331
+ }, index: Daru::Index.new([1,3,0,8,2])))
1332
+ expect(ans).to_not eq(df)
1385
1333
  end
1334
+ end
1386
1335
 
1387
- it "changes names of vectors" do
1388
- ans = Daru::DataFrame.new({
1336
+ context "#reindex_vectors" do
1337
+ it "re indexes vectors and aligns accordingly" do
1338
+ df = Daru::DataFrame.new({
1389
1339
  a: [1,2,3,4,5],
1390
1340
  b: [11,22,33,44,55],
1391
1341
  c: %w(a b c d e)
1392
- }, order: [:b, :c, :a])
1342
+ })
1393
1343
 
1394
- expect(@df.reindex_vectors!([:b,:c,:a])).to eq(Daru::Index.new([:b,:c,:a], [1,2,0]))
1395
- expect(@df[:a]).to eq(Daru::Vector.new([1,2,3,4,5]))
1396
- expect(@df[:c]).to eq(Daru::Vector.new(%w(a b c d e)))
1344
+ ans = df.reindex_vectors(Daru::Index.new([:b, 'a', :a]))
1345
+ expect(ans).to eq(Daru::DataFrame.new({
1346
+ :b => [11,22,33,44,55],
1347
+ 'a' => [nil, nil, nil, nil, nil],
1348
+ :a => [1,2,3,4,5]
1349
+ }, order: [:b, 'a', :a]))
1397
1350
  end
1398
1351
  end
1399
1352
 
@@ -1476,16 +1429,16 @@ describe Daru::DataFrame do
1476
1429
  expect(@df.pivot_table(index: [:a])).to eq(Daru::DataFrame.new({
1477
1430
  d: [5.5,2.2],
1478
1431
  e: [11.0,4.4]
1479
- }, index: [:bar, :foo]))
1432
+ }, index: ['bar', 'foo']))
1480
1433
  end
1481
1434
 
1482
1435
  it "creates row index as per (double) index argument and default aggregates to mean" do
1483
- agg_mi = Daru::MultiIndex.new(
1436
+ agg_mi = Daru::MultiIndex.from_tuples(
1484
1437
  [
1485
- [:bar, :large],
1486
- [:bar, :small],
1487
- [:foo, :large],
1488
- [:foo, :small]
1438
+ ['bar', 'large'],
1439
+ ['bar', 'small'],
1440
+ ['foo', 'large'],
1441
+ ['foo', 'small']
1489
1442
  ]
1490
1443
  )
1491
1444
  expect(@df.pivot_table(index: [:a, :c]).round(2)).to eq(Daru::DataFrame.new({
@@ -1495,46 +1448,48 @@ describe Daru::DataFrame do
1495
1448
  end
1496
1449
 
1497
1450
  it "creates row and vector index as per (single) index and (single) vectors args" do
1498
- agg_vectors = Daru::MultiIndex.new([
1499
- [:d, :one],
1500
- [:d, :two],
1501
- [:e, :one],
1502
- [:e, :two]
1451
+ agg_vectors = Daru::MultiIndex.from_tuples([
1452
+ [:d, 'one'],
1453
+ [:d, 'two'],
1454
+ [:e, 'one'],
1455
+ [:e, 'two']
1503
1456
  ])
1504
- agg_index = Daru::MultiIndex.new(
1457
+ agg_index = Daru::MultiIndex.from_tuples(
1505
1458
  [
1506
- [:bar],
1507
- [:foo]
1459
+ ['bar'],
1460
+ ['foo']
1508
1461
  ]
1509
1462
  )
1510
-
1511
- expect(@df.pivot_table(index: [:a], vectors: [:b]).round(2)).to eq(Daru::DataFrame.new(
1512
- [
1513
- [4.5, 1.67],
1514
- [6.5, 3.0],
1515
- [9.0, 3.33],
1516
- [13, 6]
1517
- ], order: agg_vectors, index: agg_index))
1463
+
1464
+ expect(@df.pivot_table(index: [:a], vectors: [:b]).round(2)).to eq(
1465
+ Daru::DataFrame.new(
1466
+ [
1467
+ [4.5, 1.67],
1468
+ [6.5, 3.0],
1469
+ [9.0, 3.33],
1470
+ [13, 6]
1471
+ ], order: agg_vectors, index: agg_index)
1472
+ )
1518
1473
  end
1519
1474
 
1520
1475
  it "creates row and vector index as per (single) index and (double) vector args" do
1521
- agg_vectors = Daru::MultiIndex.new(
1476
+ agg_vectors = Daru::MultiIndex.from_tuples(
1522
1477
  [
1523
- [:d, :one, :large],
1524
- [:d, :one, :small],
1525
- [:d, :two, :large],
1526
- [:d, :two, :small],
1527
- [:e, :one, :large],
1528
- [:e, :one, :small],
1529
- [:e, :two, :large],
1530
- [:e, :two, :small]
1478
+ [:d, 'one', 'large'],
1479
+ [:d, 'one', 'small'],
1480
+ [:d, 'two', 'large'],
1481
+ [:d, 'two', 'small'],
1482
+ [:e, 'one', 'large'],
1483
+ [:e, 'one', 'small'],
1484
+ [:e, 'two', 'large'],
1485
+ [:e, 'two', 'small']
1531
1486
  ]
1532
1487
  )
1533
1488
 
1534
- agg_index = Daru::MultiIndex.new(
1489
+ agg_index = Daru::MultiIndex.from_tuples(
1535
1490
  [
1536
- [:bar],
1537
- [:foo]
1491
+ ['bar'],
1492
+ ['foo']
1538
1493
  ]
1539
1494
  )
1540
1495
 
@@ -1553,21 +1508,21 @@ describe Daru::DataFrame do
1553
1508
  end
1554
1509
 
1555
1510
  it "creates row and vector index with (double) index and (double) vector args" do
1556
- agg_index = Daru::MultiIndex.new([
1557
- [:bar, 4],
1558
- [:bar, 5],
1559
- [:bar, 6],
1560
- [:bar, 7],
1561
- [:foo, 1],
1562
- [:foo, 2],
1563
- [:foo, 3]
1511
+ agg_index = Daru::MultiIndex.from_tuples([
1512
+ ['bar', 4],
1513
+ ['bar', 5],
1514
+ ['bar', 6],
1515
+ ['bar', 7],
1516
+ ['foo', 1],
1517
+ ['foo', 2],
1518
+ ['foo', 3]
1564
1519
  ])
1565
1520
 
1566
- agg_vectors = Daru::MultiIndex.new([
1567
- [:e, :one, :large],
1568
- [:e, :one, :small],
1569
- [:e, :two, :large],
1570
- [:e, :two, :small]
1521
+ agg_vectors = Daru::MultiIndex.from_tuples([
1522
+ [:e, 'one', 'large'],
1523
+ [:e, 'one', 'small'],
1524
+ [:e, 'two', 'large'],
1525
+ [:e, 'two', 'small']
1571
1526
  ])
1572
1527
 
1573
1528
  expect(@df.pivot_table(index: [:a, :d], vectors: [:b, :c])).to eq(
@@ -1582,18 +1537,18 @@ describe Daru::DataFrame do
1582
1537
  end
1583
1538
 
1584
1539
  it "only aggregates over the vector specified in the values argument" do
1585
- agg_vectors = Daru::MultiIndex.new(
1540
+ agg_vectors = Daru::MultiIndex.from_tuples(
1586
1541
  [
1587
- [:e, :one, :large],
1588
- [:e, :one, :small],
1589
- [:e, :two, :large],
1590
- [:e, :two, :small]
1542
+ [:e, 'one', 'large'],
1543
+ [:e, 'one', 'small'],
1544
+ [:e, 'two', 'large'],
1545
+ [:e, 'two', 'small']
1591
1546
  ]
1592
1547
  )
1593
- agg_index = Daru::MultiIndex.new(
1548
+ agg_index = Daru::MultiIndex.from_tuples(
1594
1549
  [
1595
- [:bar],
1596
- [:foo]
1550
+ ['bar'],
1551
+ ['foo']
1597
1552
  ]
1598
1553
  )
1599
1554
  expect(@df.pivot_table(index: [:a], vectors: [:b, :c], values: :e)).to eq(
@@ -1609,18 +1564,18 @@ describe Daru::DataFrame do
1609
1564
  end
1610
1565
 
1611
1566
  it "overrides default aggregate function to aggregate over sum" do
1612
- agg_vectors = Daru::MultiIndex.new(
1567
+ agg_vectors = Daru::MultiIndex.from_tuples(
1613
1568
  [
1614
- [:e, :one, :large],
1615
- [:e, :one, :small],
1616
- [:e, :two, :large],
1617
- [:e, :two, :small]
1569
+ [:e, 'one', 'large'],
1570
+ [:e, 'one', 'small'],
1571
+ [:e, 'two', 'large'],
1572
+ [:e, 'two', 'small']
1618
1573
  ]
1619
1574
  )
1620
- agg_index = Daru::MultiIndex.new(
1575
+ agg_index = Daru::MultiIndex.from_tuples(
1621
1576
  [
1622
- [:bar],
1623
- [:foo]
1577
+ ['bar'],
1578
+ ['foo']
1624
1579
  ]
1625
1580
  )
1626
1581
  expect(@df.pivot_table(index: [:a], vectors: [:b, :c], values: :e, agg: :sum)).to eq(
@@ -1908,15 +1863,15 @@ describe Daru::DataFrame do
1908
1863
  df = Daru::DataFrame.crosstab_by_assignation(v1, v2, v3)
1909
1864
 
1910
1865
  expect(df[:_id].type).to eq(:object)
1911
- expect(df[:a].type).to eq(:numeric)
1912
- expect(df[:b].type).to eq(:numeric)
1866
+ expect(df['a'].type).to eq(:numeric)
1867
+ expect(df['b'].type).to eq(:numeric)
1913
1868
 
1914
1869
  ev_id = Daru::Vector.new %w(a b c)
1915
1870
  ev_a = Daru::Vector.new [0, 0, 0]
1916
1871
  ev_b = Daru::Vector.new [1, 1, 0]
1917
1872
  ev_c = Daru::Vector.new [0, 1, 1]
1918
1873
  df2 = Daru::DataFrame.new({
1919
- :_id => ev_id, :a => ev_a, :b => ev_b, :c => ev_c })
1874
+ :_id => ev_id, 'a' => ev_a, 'b' => ev_b, 'c' => ev_c })
1920
1875
 
1921
1876
  expect(df2).to eq(df)
1922
1877
  end
@@ -1929,19 +1884,21 @@ describe Daru::DataFrame do
1929
1884
  ['2', 'fred', 'green', 15, 'orange', 30, 'white', 20],
1930
1885
  ['3', 'alfred', nil, nil, nil, nil, nil, nil]
1931
1886
  ]
1887
+
1932
1888
  df = Daru::DataFrame.rows(rows,
1933
- order: [:id, :name, :car_color1, :car_value1, :car_color2,
1934
- :car_value2, :car_color3, :car_value3])
1889
+ order: ['id', 'name', 'car_color1', 'car_value1', 'car_color2',
1890
+ 'car_value2', 'car_color3', 'car_value3'])
1935
1891
 
1936
1892
  ids = Daru::Vector.new %w(1 1 2 2 2)
1937
1893
  colors = Daru::Vector.new %w(red blue green orange white)
1938
1894
  values = Daru::Vector.new [10, 20, 15, 30, 20]
1939
1895
  col_ids = Daru::Vector.new [1, 2, 1, 2, 3]
1896
+
1940
1897
  df_expected = Daru::DataFrame.new({
1941
- :id => ids, :_col_id => col_ids, :color => colors, :value => values
1942
- }, order: [:id, :_col_id, :color, :value])
1898
+ 'id' => ids, '_col_id' => col_ids, 'color' => colors, 'value' => values
1899
+ }, order: ['id', '_col_id', 'color', 'value'])
1943
1900
 
1944
- expect(df.one_to_many([:id], 'car_%v%n')).to eq(df_expected)
1901
+ expect(df.one_to_many(['id'], 'car_%v%n')).to eq(df_expected)
1945
1902
  end
1946
1903
  end
1947
1904
 
@@ -2023,7 +1980,7 @@ describe Daru::DataFrame do
2023
1980
 
2024
1981
  context Daru::MultiIndex do
2025
1982
  before do
2026
- agg_vectors = Daru::MultiIndex.new(
1983
+ agg_vectors = Daru::MultiIndex.from_tuples(
2027
1984
  [
2028
1985
  [:d, :one, :large],
2029
1986
  [:d, :one, :small],
@@ -2036,7 +1993,7 @@ describe Daru::DataFrame do
2036
1993
  ]
2037
1994
  )
2038
1995
 
2039
- agg_index = Daru::MultiIndex.new(
1996
+ agg_index = Daru::MultiIndex.from_tuples(
2040
1997
  [
2041
1998
  [:bar],
2042
1999
  [:foo]
@@ -2057,7 +2014,7 @@ describe Daru::DataFrame do
2057
2014
  end
2058
2015
 
2059
2016
  it "returns numeric vectors" do
2060
- vectors = Daru::MultiIndex.new(
2017
+ vectors = Daru::MultiIndex.from_tuples(
2061
2018
  [
2062
2019
  [:d, :one, :large],
2063
2020
  [:d, :two, :large],
@@ -2068,7 +2025,7 @@ describe Daru::DataFrame do
2068
2025
  ]
2069
2026
  )
2070
2027
 
2071
- index = Daru::MultiIndex.new(
2028
+ index = Daru::MultiIndex.from_tuples(
2072
2029
  [
2073
2030
  [:bar],
2074
2031
  [:foo]
@@ -2089,4 +2046,45 @@ describe Daru::DataFrame do
2089
2046
  end
2090
2047
  end
2091
2048
  end
2049
+
2050
+ context "#set_index" do
2051
+ before(:each) do
2052
+ @df = Daru::DataFrame.new({
2053
+ a: [1,2,3,4,5],
2054
+ b: ['a','b','c','d','e'],
2055
+ c: [11,22,33,44,55]
2056
+ })
2057
+ end
2058
+
2059
+ it "sets a particular column as the index and deletes that column" do
2060
+ @df.set_index(:b)
2061
+ expect(@df).to eq(
2062
+ Daru::DataFrame.new({
2063
+ a: [1,2,3,4,5],
2064
+ c: [11,22,33,44,55]
2065
+ }, index: ['a','b','c','d','e'])
2066
+ )
2067
+ end
2068
+
2069
+ it "sets a particular column as index but keeps that column" do
2070
+ expect(@df.set_index(:c, keep: true)).to eq(
2071
+ Daru::DataFrame.new({
2072
+ a: [1,2,3,4,5],
2073
+ b: ['a','b','c','d','e'],
2074
+ c: [11,22,33,44,55]
2075
+ }, index: [11,22,33,44,55]))
2076
+ expect(@df[:c]).to eq(@df[:c])
2077
+ end
2078
+
2079
+ it "raises error if all elements in the column aren't unique" do
2080
+ jholu = Daru::DataFrame.new({
2081
+ a: ['a','b','a'],
2082
+ b: [1,2,4]
2083
+ })
2084
+
2085
+ expect {
2086
+ jholu.set_index(:a)
2087
+ }.to raise_error(ArgumentError)
2088
+ end
2089
+ end
2092
2090
  end if mri?