spec/vector_spec.rb in daru-0.1.0 vs spec/vector_spec.rb in daru-0.1.1

- old
+ new

@@ -16,11 +16,11 @@ [:a, :two, :bar], [:b, :one, :bar], [:b, :two, :baz] ] - @multi_index = Daru::MultiIndex.new(@tuples) + @multi_index = Daru::MultiIndex.from_tuples(@tuples) end it "initializes from an Array" do dv = Daru::Vector.new [1,2,3,4,5], name: :ravan, index: [:ek, :don, :teen, :char, :pach], dtype: dtype @@ -75,10 +75,16 @@ it "inserts nils for extra indices (MultiIndex)" do dv = Daru::Vector.new [1,2], name: :mi, index: @multi_index, dtype: :array expect(dv).to eq(Daru::Vector.new([1,2,nil,nil], name: :mi, index: @multi_index, dtype: :array)) end + + it "accepts all sorts of objects for indexing" do + dv = Daru::Vector.new [1,2,3,4], index: ['a', 'b', :r, 0] + expect(dv.to_a).to eq([1,2,3,4]) + expect(dv.index.to_a).to eq(['a', 'b', :r, 0]) + end end context ".new_with_size" do it "creates new vector from only size" do v1 = Daru::Vector.new 10.times.map { nil }, dtype: dtype @@ -145,10 +151,18 @@ it "returns a vector when specified numeric Range" do expect(@dv[3..4]).to eq(Daru::Vector.new([4,5], name: :yoga, index: [:padme, :r2d2], dtype: dtype)) end + + it "returns correct results for index of multiple index" do + v = Daru::Vector.new([1,2,3,4], index: ['a','c',1,:a]) + expect(v['a']).to eq(1) + expect(v[:a]).to eq(4) + expect(v[1]).to eq(3) + expect(v[0]).to eq(1) + end end context Daru::MultiIndex do before do @tuples = [ @@ -163,13 +177,14 @@ [:c,:one,:bar], [:c,:one,:baz], [:c,:two,:foo], [:c,:two,:bar] ] - @multi_index = Daru::MultiIndex.new(@tuples) - @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index, - dtype: dtype, name: :mi_vector + @multi_index = Daru::MultiIndex.from_tuples(@tuples) + @vector = Daru::Vector.new( + Array.new(12) { |i| i }, index: @multi_index, + dtype: dtype, name: :mi_vector) end it "returns a single element when passed a row number" do expect(@vector[1]).to eq(1) end @@ -177,29 +192,29 @@ it "returns a single element when passed the full tuple" do expect(@vector[:a, :one, :baz]).to eq(1) end it "returns sub vector when passed first layer of tuple" do - mi = Daru::MultiIndex.new([ + mi = Daru::MultiIndex.from_tuples([ [:one,:bar], [:one,:baz], [:two,:bar], [:two,:baz]]) expect(@vector[:a]).to eq(Daru::Vector.new([0,1,2,3], index: mi, dtype: dtype, name: :sub_vector)) end it "returns sub vector when passed first and second layer of tuple" do - mi = Daru::MultiIndex.new([ + mi = Daru::MultiIndex.from_tuples([ [:foo], [:bar]]) expect(@vector[:c,:two]).to eq(Daru::Vector.new([10,11], index: mi, dtype: dtype, name: :sub_sub_vector)) end it "returns a vector with corresponding MultiIndex when specified numeric Range" do - mi = Daru::MultiIndex.new([ + mi = Daru::MultiIndex.from_tuples([ [:a,:two,:baz], [:b,:one,:bar], [:b,:two,:bar], [:b,:two,:baz], [:b,:one,:foo], @@ -231,10 +246,25 @@ it "sets dtype to Array if a nil is assigned" do @dv[0] = nil expect(@dv.dtype).to eq(:array) end + + it "assigns correctly for a mixed index Vector" do + v = Daru::Vector.new [1,2,3,4], index: ['a',:a,0,66] + v['a'] = 666 + expect(v['a']).to eq(666) + + v[0] = 666 + expect(v[0]).to eq(666) + + v[3] = 666 + expect(v[3]).to eq(666) + + expect(v).to eq(Daru::Vector.new([666,2,666,666], + index: ['a',:a,0,66])) + end end context Daru::MultiIndex do before :each do @tuples = [ @@ -249,11 +279,11 @@ [:c,:one,:bar], [:c,:one,:baz], [:c,:two,:foo], [:c,:two,:bar] ] - @multi_index = Daru::MultiIndex.new(@tuples) + @multi_index = Daru::MultiIndex.from_tuples(@tuples) @vector = Daru::Vector.new Array.new(12) { |i| i }, index: @multi_index, dtype: dtype, name: :mi_vector end it "assigns all lower layer indices when specified a first layer index" do @@ -291,25 +321,16 @@ it "concatenates a new element at the end of vector with index" do @dv.concat 6, :ibanez expect(@dv.index) .to eq( - [:warwick, :thompson, :jackson, :fender, :esp, :ibanez].to_index) + Daru::Index.new([:warwick, :thompson, :jackson, :fender, :esp, :ibanez])) expect(@dv[:ibanez]).to eq(6) expect(@dv[5]) .to eq(6) end - it "concatenates without index if index is default numeric" do - vector = Daru::Vector.new [1,2,3,4,5], name: :nums, dtype: dtype - - vector.concat 6 - - expect(vector.index).to eq([0,1,2,3,4,5].to_index) - expect(vector[5]) .to eq(6) - end - - it "raises error if index not specified and non-numeric index" do + it "raises error if index not specified" do expect { @dv.concat 6 }.to raise_error end end @@ -318,17 +339,14 @@ context Daru::Index do it "deletes specified value in the vector" do dv = Daru::Vector.new [1,2,3,4,5], name: :a, dtype: dtype dv.delete 3 - expect(dv).to eq(Daru::Vector.new [1,2,4,5], name: :a) + expect(dv).to eq( + Daru::Vector.new [1,2,4,5], name: :a, index: [0,1,3,4]) end end - - context Daru::MultiIndex do - pending - end end context "#delete_at" do context Daru::Index do before :each do @@ -342,33 +360,41 @@ expect(@dv).to eq(Daru::Vector.new [2,3,4,5], name: :a, index: [:two, :three, :four, :five], dtype: dtype) end it "deletes element of specified integer index" do + pending @dv.delete_at 2 expect(@dv).to eq(Daru::Vector.new [1,2,4,5], name: :a, index: [:one, :two, :four, :five], dtype: dtype) end end - - context Daru::MultiIndex do - pending "Possibly next release" - end end context "#delete_if" do it "deletes elements if block evaluates to true" do v = Daru::Vector.new [1,22,33,45,65,32,524,656,123,99,77], dtype: dtype - ret = v.delete_if { |d| d % 11 != 0 } + ret = v.delete_if { |d| d % 11 == 0 } expect(ret).to eq( Daru::Vector.new([1,45,65,32,524,656,123], index: [0,3,4,5,6,7,8], dtype: dtype)) expect(ret.dtype).to eq(dtype) end end + context "#keep_if" do + it "keeps elements if block returns true" do + v = Daru::Vector.new([1,22,33,45,65,32,524,656,123,99,77], dtype: dtype) + ret = v.keep_if { |d| d < 35 } + + expect(ret).to eq( + Daru::Vector.new([1,22,33,32], index: [0,1,2,5], dtype: dtype)) + expect(v.dtype).to eq(ret.dtype) + end + end + context "#index_of" do context Daru::Index do it "returns index of specified value" do dv = Daru::Vector.new [1,2,3,4,5], name: :a, index: [:one, :two, :three, :four, :five], dtype: dtype @@ -377,11 +403,11 @@ end end context Daru::MultiIndex do it "returns tuple of specified value" do - mi = Daru::MultiIndex.new([ + mi = Daru::MultiIndex.from_tuples([ [:a,:two,:bar], [:a,:two,:baz], [:b,:one,:bar], [:b,:two,:bar] ]) @@ -403,11 +429,11 @@ context Daru::MultiIndex do pending # it "returns vector as a Hash" do # pending - # mi = Daru::MultiIndex.new([ + # mi = Daru::MultiIndex.from_tuples([ # [:a,:two,:bar], # [:a,:two,:baz], # [:b,:one,:bar], # [:b,:two,:bar] # ]) @@ -467,11 +493,11 @@ end if dtype == :array end context Daru::MultiIndex do before do - mi = Daru::MultiIndex.new([ + mi = Daru::MultiIndex.from_tuples([ [:a, :one, :foo], [:a, :two, :bar], [:b, :one, :bar], [:b, :two, :baz], [:b, :three, :bar] @@ -479,11 +505,11 @@ @vector = Daru::Vector.new([44,22,111,0,-56], index: mi, name: :unsorted, dtype: dtype) end it "sorts vector" do - mi_asc = Daru::MultiIndex.new([ + mi_asc = Daru::MultiIndex.from_tuples([ [:b, :three, :bar], [:b, :two, :baz], [:a, :two, :bar], [:a, :one, :foo], [:b, :one, :bar] @@ -491,11 +517,11 @@ expect(@vector.sort).to eq(Daru::Vector.new([-56,0,22,44,111], index: mi_asc, name: :ascending, dtype: dtype)) end it "sorts in descending" do - mi_dsc = Daru::MultiIndex.new([ + mi_dsc = Daru::MultiIndex.from_tuples([ [:b, :one, :bar], [:a, :one, :foo], [:a, :two, :bar], [:b, :two, :baz], [:b, :three, :bar] @@ -503,11 +529,11 @@ expect(@vector.sort(ascending: false)).to eq(Daru::Vector.new( [111,44,22,0,-56], index: mi_dsc, name: :descending, dtype: dtype)) end it "sorts using the supplied block" do - mi_abs = Daru::MultiIndex.new([ + mi_abs = Daru::MultiIndex.from_tuples([ [:b, :two, :baz], [:a, :two, :bar], [:a, :one, :foo], [:b, :three, :bar], [:b, :one, :bar] @@ -516,33 +542,37 @@ [0,22,44,-56,111], index: mi_abs, name: :sort_abs, dtype: dtype)) end end end - context "#reindex" do - context Daru::Index do - before do - @dv = Daru::Vector.new [1,2,3,4,5], name: :dv, index: [:a, :b, :c, :d, :e] - end + context "#index=" do + before do + @vector = Daru::Vector.new([1,2,3,4,5]) + end - it "recreates index with sequential numbers" do - a = @dv.reindex(:seq) + it "simply reassigns index" do + index = Daru::DateTimeIndex.date_range(:start => '2012', :periods => 5) + @vector.index = index - expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [0,1,2,3,4])) - expect(a).to_not eq(@dv) - end + expect(@vector.index.class).to eq(DateTimeIndex) + expect(@vector['2012-1-1']).to eq(1) + end - it "accepts a new non-numeric index" do - a = @dv.reindex([:hello, :my, :name, :is, :ted]) - - expect(a).to eq(Daru::Vector.new([1,2,3,4,5], name: :dv, index: [:hello, :my, :name, :is, :ted])) - expect(a).to_not eq(@dv) - end + it "raises error for index size != vector size" do + expect { + @vector.index = Daru::Index.new([4,2,6]) + }.to raise_error end + end - context Daru::MultiIndex do - pending + context "#reindex" do + it "intelligently reindexes" do + vector = Daru::Vector.new([1,2,3,4,5]) + index = Daru::Index.new([3,4,1,0,6]) + + expect(vector.reindex(index)).to eq( + Daru::Vector.new([4,5,2,1,nil], index: index)) end end context "#collect" do it "returns an Array" do @@ -737,11 +767,28 @@ expect(@with_md.missing_positions).to eq([2,3,5]) end end context Daru::MultiIndex do - pending + it "returns indexes of nils" do + mi = Daru::MultiIndex.from_tuples([ + ['M', 2000], + ['M', 2001], + ['M', 2002], + ['M', 2003], + ['F', 2000], + ['F', 2001], + ['F', 2002], + ['F', 2003] + ]) + vector = Daru::Vector.new([nil,2,4,5,3,nil,2,nil], index: mi) + expect(vector.missing_positions).to eq([ + ['M',2000], + ['F',2001], + ['F',2003] + ]) + end end end context "#replace_nils" do it "replaces all nils with the specified value" do @@ -755,13 +802,13 @@ end end context "#type" do before(:each) do - @numeric = Daru::Vector.new([1,2,3,4,5]) - @multi = Daru::Vector.new([1,2,3,'sameer','d']) - @with_nils = Daru::Vector.new([1,2,3,4,nil]) + @numeric = Daru::Vector.new([1,2,3,4,5]) + @multi = Daru::Vector.new([1,2,3,'sameer','d']) + @with_nils = Daru::Vector.new([1,2,3,4,nil]) end it "checks numeric data correctly" do expect(@numeric.type).to eq(:numeric) end @@ -920,11 +967,11 @@ expect(@v.name).to eq(:that_vector) end it "stores name as a symbol" do @v.rename "This is a vector" - expect(@v.name).to eq(:"This is a vector") + expect(@v.name).to eq("This is a vector") end end context "#any?" do before do @@ -964,13 +1011,31 @@ end end context "#detach_index" do it "creates a DataFrame with first Vector as index and second as values of the Vector" do - v = Daru::Vector.new([1,2,3,4,5,6], index: [:a, :b, :c, :d, :e, :f], name: :values) + v = Daru::Vector.new([1,2,3,4,5,6], + index: ['a', 'b', 'c', 'd', 'e', 'f'], name: :values) expect(v.detach_index).to eq(Daru::DataFrame.new({ index: ['a', 'b', 'c', 'd', 'e', 'f'], - vector: [1,2,3,4,5,6] + values: [1,2,3,4,5,6] })) + end + end + + context "#lag" do + it "lags the vector by specified amount" do + xiu = Daru::Vector.new([17.28, 17.45, 17.84, 17.74, 17.82, 17.85, 17.36, 17.3, 17.56, 17.49, 17.46, 17.4, 17.03, 17.01, + 16.86, 16.86, 16.56, 16.36, 16.66, 16.77]) + lag1 = xiu.lag + + expect(lag1[lag1.size - 1]).to be_within(0.001).of(16.66) + expect(lag1[lag1.size - 2]).to be_within(0.001).of(16.36) + + #test with different lagging unit + lag2 = xiu.lag(2) + + expect(lag2[lag2.size - 1]).to be_within(0.001).of(16.36) + expect(lag2[lag2.size - 2]).to be_within(0.001).of(16.56) end end end if mri?