spec/vector_spec.rb in daru-0.1.5 vs spec/vector_spec.rb in daru-0.1.6
- old
+ new
@@ -82,10 +82,15 @@
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
+ it "initializes array with nils with dtype NMatrix" do
+ dv = Daru::Vector.new [2, nil], dtype: :nmatrix
+ expect(dv.to_a).to eq([2, nil])
+ expect(dv.index.to_a).to eq([0, 1])
+ end
end
context "#reorder!" do
let(:vector_with_dtype) do
Daru::Vector.new(
@@ -356,10 +361,13 @@
context "#at" do
context Daru::Index do
let (:idx) { Daru::Index.new [1, 0, :c] }
let (:dv) { Daru::Vector.new ['a', 'b', 'c'], index: idx }
+ let (:idx_dt) { Daru::DateTimeIndex.new(['2017-01-01', '2017-02-01', '2017-03-01']) }
+ let (:dv_dt) { Daru::Vector.new(['a', 'b', 'c'], index: idx_dt) }
+
context "single position" do
it { expect(dv.at 1).to eq 'b' }
end
context "multiple positions" do
@@ -403,10 +411,19 @@
it { is_expected.to be_a Daru::Vector }
its(:size) { is_expected.to eq 1 }
its(:to_a) { is_expected.to eq ['a'] }
its(:'index.to_a') { is_expected.to eq [1] }
end
+
+ context "Splat .at on DateTime index" do
+ subject { dv_dt.at(*[1,2]) }
+
+ it { is_expected.to be_a Daru::Vector }
+ its(:size) { is_expected.to eq 2 }
+ its(:to_a) { is_expected.to eq ['b', 'c'] }
+ its(:'index.to_a') { is_expected.to eq ['2017-02-01', '2017-03-01'] }
+ end
end
context Daru::MultiIndex do
let (:idx) do
Daru::MultiIndex.from_tuples [
@@ -996,10 +1013,30 @@
end
its(:to_json) { is_expected.to eq(vector.to_h.to_json) }
end
+ context "#to_s" do
+ before do
+ @v = Daru::Vector.new ["a", "b"], index: [1, 2]
+ end
+
+ it 'produces a class, size description' do
+ expect(@v.to_s).to eq("#<Daru::Vector(2)>")
+ end
+
+ it 'produces a class, name, size description' do
+ @v.name = "Test"
+ expect(@v.to_s).to eq("#<Daru::Vector: Test(2)>")
+ end
+
+ it 'produces a class, name, size description when the name is a symbol' do
+ @v.name = :Test
+ expect(@v.to_s).to eq("#<Daru::Vector: Test(2)>")
+ end
+ end
+
context "#uniq" do
before do
@v = Daru::Vector.new [1, 2, 2, 2.0, 3, 3.0], index:[:a, :b, :c, :d, :e, :f]
end
it "keeps only unique values" do
@@ -1357,13 +1394,80 @@
expect(h).to eq(e)
end
end
context "#summary" do
- it "has name in the summary" do
- expect(@common_all_dtypes.summary.match("#{@common_all_dtypes.name}")).to_not eq(nil)
+ subject { dv.summary }
+
+ context 'all types' do
+ let(:dv) { Daru::Vector.new([1,2,3,4,5], name: 'vector') }
+
+ it { is_expected.to include dv.name }
+
+ it { is_expected.to include "n :#{dv.size}" }
+
+ it { is_expected.to include "non-missing:#{dv.size - dv.count_values(*Daru::MISSING_VALUES)}" }
end
+
+ unless dtype == :nmatrix
+ context "numeric type" do
+ let(:dv) { Daru::Vector.new([1,2,5], name: 'numeric') }
+
+ it { is_expected. to eq %Q{
+ |= numeric
+ | n :3
+ | non-missing:3
+ | median: 2
+ | mean: 2.6667
+ | std.dev.: 2.0817
+ | std.err.: 1.2019
+ | skew: 0.2874
+ | kurtosis: -2.3333
+ }.unindent }
+ end
+
+ context "numeric type with missing values" do
+ let(:dv) { Daru::Vector.new([1,2,5,nil,Float::NAN], name: 'numeric') }
+
+ it { is_expected.not_to include 'skew' }
+ it { is_expected.not_to include 'kurtosis' }
+ end
+ end
+
+ if dtype == :array
+ context "object type" do
+ let(:dv) { Daru::Vector.new([1,1,2,2,"string",nil,Float::NAN], name: 'object') }
+
+ if RUBY_VERSION >= '2.2'
+ it { is_expected.to eq %Q{
+ |= object
+ | n :7
+ | non-missing:5
+ | factors: 1,2,string
+ | mode: 1,2
+ | Distribution
+ | string 1 50.00%
+ | NaN 1 50.00%
+ | 1 2 100.00%
+ | 2 2 100.00%
+ }.unindent }
+ else
+ it { is_expected.to eq %Q{
+ |= object
+ | n :7
+ | non-missing:5
+ | factors: 1,2,string
+ | mode: 1,2
+ | Distribution
+ | NaN 1 50.00%
+ | string 1 50.00%
+ | 2 2 100.00%
+ | 1 2 100.00%
+ }.unindent }
+ end
+ end
+ end
end
context "#bootstrap" do
it "returns a vector with mean=mu and sd=se" do
rng = Distribution::Normal.rng(0, 1)
@@ -1386,32 +1490,24 @@
a = Daru::Vector.new ['a', 'a,b', 'c,d', 'a,d', 'd', 10, nil]
expect(a.splitted).to eq([%w(a), %w(a b), %w(c d), %w(a d), %w(d), [10], nil])
end
end
- context "#is_nil?" do
- before(:each) do
- @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
- @without_md = Daru::Vector.new([1,2,3,4,5,6])
- end
+ context '#is_values' do
+ let(:dv) { Daru::Vector.new [10, 11, 10, nil, nil] }
- it "verifies missing data presence" do
- expect(@with_md.is_nil?) .to eq(Daru::Vector.new([false,false,true,false,false,true]))
- expect(@without_md.is_nil?).to eq(Daru::Vector.new([false,false,false,false,false,false]))
+ context 'single value' do
+ subject { dv.is_values 10 }
+ it { is_expected.to be_a Daru::Vector }
+ its(:to_a) { is_expected.to eq [true, false, true, false, false] }
end
- end
- context "#not_nil?" do
- before(:each) do
- @with_md = Daru::Vector.new([1,2,nil,3,4,nil])
- @without_md = Daru::Vector.new([1,2,3,4,5,6])
+ context 'multiple values' do
+ subject { dv.is_values 10, nil }
+ it { is_expected.to be_a Daru::Vector }
+ its(:to_a) { is_expected.to eq [true, false, true, true, true] }
end
-
- it "verifies missing data presence" do
- expect(@with_md.not_nil?) .to eq(Daru::Vector.new([true,true,false,true,true,false]))
- expect(@without_md.not_nil?).to eq(Daru::Vector.new([true,true,true,true,true,true]))
- end
end
context "#clone_structure" do
context Daru::Index do
before do
@@ -1431,61 +1527,61 @@
context '#reject_values'do
let(:dv) { Daru::Vector.new [1, nil, 3, :a, Float::NAN, nil, Float::NAN, 1],
index: 11..18 }
context 'reject only nils' do
subject { dv.reject_values nil }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
end
context 'reject only float::NAN' do
subject { dv.reject_values Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
end
context 'reject both nil and float::NAN' do
subject { dv.reject_values nil, Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
end
-
+
context 'reject any other value' do
subject { dv.reject_values 1, 3 }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
end
context 'when resultant vector has only one value' do
subject { dv.reject_values 1, :a, nil, Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [3] }
its(:'index.to_a') { is_expected.to eq [13] }
end
-
+
context 'when resultant vector has no value' do
subject { dv.reject_values 1, 3, :a, nil, Float::NAN, 5 }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [] }
its(:'index.to_a') { is_expected.to eq [] }
end
-
+
context 'works for gsl' do
let(:dv) { Daru::Vector.new [1, 2, 3, Float::NAN], dtype: :gsl,
index: 11..14 }
subject { dv.reject_values Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:dtype) { is_expected.to eq :gsl }
its(:to_a) { is_expected.to eq [1, 2, 3].map(&:to_f) }
its(:'index.to_a') { is_expected.to eq [11, 12, 13] }
end
@@ -1499,35 +1595,35 @@
end
end
context 'reject only nils' do
subject { dv.reject_values nil }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, 3, :a, Float::NAN, Float::NAN, 1] }
its(:'index.to_a') { is_expected.to eq [11, 13, 14, 15, 17, 18] }
end
-
+
context 'reject only float::NAN' do
subject { dv.reject_values Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, nil, 3, :a, nil, 1] }
its(:'index.to_a') { is_expected.to eq [11, 12, 13, 14, 16, 18] }
end
-
+
context 'reject both nil and float::NAN' do
subject { dv.reject_values nil, Float::NAN }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [1, 3, :a, 1] }
its(:'index.to_a') { is_expected.to eq [11, 13, 14, 18] }
end
-
+
context 'reject any other value' do
subject { dv.reject_values 1, 3 }
-
+
it { is_expected.to be_a Daru::Vector }
its(:to_a) { is_expected.to eq [nil, :a, Float::NAN, nil, Float::NAN] }
its(:'index.to_a') { is_expected.to eq [12, 14, 15, 16, 17] }
end
end
@@ -1561,28 +1657,28 @@
context 'both nil and Float::NAN' do
context 'true with only nil' do
let(:dv) { Daru::Vector.new [1, Float::NAN, 2, 3] }
it { expect(dv.include_values? nil, Float::NAN).to eq true }
end
-
+
context 'true with only Float::NAN' do
let(:dv) { Daru::Vector.new [1, nil, 2, 3] }
it { expect(dv.include_values? nil, Float::NAN).to eq true }
end
-
+
context 'false' do
let(:dv) { Daru::Vector.new [1, 2, 3] }
it { expect(dv.include_values? nil, Float::NAN).to eq false }
end
end
-
+
context 'any other value' do
context 'true' do
let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
it { expect(dv.include_values? 1, 2, 3, 5).to eq true }
end
-
+
context 'false' do
let(:dv) { Daru::Vector.new [1, 2, 3, 4, nil] }
it { expect(dv.include_values? 5, 6).to eq false }
end
end
@@ -1598,16 +1694,16 @@
context '#indexes' do
context Daru::Index do
let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
index: 11..18 }
-
+
subject { dv.indexes 1, 2, nil, Float::NAN }
it { is_expected.to be_a Array }
it { is_expected.to eq [11, 12, 13, 14, 16, 17, 18] }
end
-
+
context Daru::MultiIndex do
let(:mi) do
Daru::MultiIndex.from_tuples([
['M', 2000],
['M', 2001],
@@ -1619,11 +1715,11 @@
['F', 2003]
])
end
let(:dv) { Daru::Vector.new [1, 2, 1, 2, 3, nil, nil, Float::NAN],
index: mi }
-
+
subject { dv.indexes 1, 2, Float::NAN }
it { is_expected.to be_a Array }
it { is_expected.to eq(
[
['M', 2000],
@@ -1632,11 +1728,11 @@
['M', 2003],
['F', 2003]
]) }
end
end
-
+
context '#replace_values' do
subject do
Daru::Vector.new(
[1, 2, 1, 4, nil, Float::NAN, nil, Float::NAN],
index: 11..18
@@ -1645,17 +1741,17 @@
context 'replace nils and NaNs' do
before { subject.replace_values [nil, Float::NAN], 10 }
its(:to_a) { is_expected.to eq [1, 2, 1, 4, 10, 10, 10, 10] }
end
-
+
context 'replace arbitrary values' do
before { subject.replace_values [1, 2], 10 }
its(:to_a) { is_expected.to eq(
[10, 10, 10, 4, nil, Float::NAN, nil, Float::NAN]) }
end
-
+
context 'works for single value' do
before { subject.replace_values nil, 10 }
its(:to_a) { is_expected.to eq(
[1, 2, 1, 4, 10, Float::NAN, 10, Float::NAN]) }
end
@@ -1739,31 +1835,31 @@
end
end
context '#to_nmatrix' do
let(:dv) { Daru::Vector.new [1, 2, 3, 4, 5] }
-
+
context 'horizontal axis' do
subject { dv.to_nmatrix }
it { is_expected.to be_a NMatrix }
its(:shape) { is_expected.to eq [1, 5] }
its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5] }
end
-
+
context 'vertical axis' do
subject { dv.to_nmatrix :vertical }
-
+
it { is_expected.to be_a NMatrix }
its(:shape) { is_expected.to eq [5, 1] }
its(:to_a) { is_expected.to eq [1, 2, 3, 4, 5].map { |i| [i] } }
end
-
+
context 'invalid axis' do
it { expect { dv.to_nmatrix :hello }.to raise_error ArgumentError }
end
-
+
context 'vector contain non-numeric' do
let(:dv) { Daru::Vector.new [1, 2, nil, 4] }
it { expect { dv.to_nmatrix }.to raise_error ArgumentError }
end
end
@@ -1902,50 +1998,77 @@
values: [1,2,3,4,5,6]
}))
end
end
- context "#lag" do
- before 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])
+ describe '#lag' do
+ let(:source) { Daru::Vector.new(1..5) }
+
+ context 'by default' do
+ subject { source.lag }
+ it { is_expected.to eq Daru::Vector.new([nil, 1, 2, 3, 4]) }
end
- it "lags the vector by specified amount" do
- lag1 = @xiu.lag
+ subject { source.lag(amount) }
- 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)
+ context '0' do
+ let(:amount) { 0 }
+ it { is_expected.to eq Daru::Vector.new([1, 2, 3, 4, 5]) }
+ end
- #test with different lagging unit
- lag2 = @xiu.lag(2)
+ context 'same as vector size' do
+ let(:amount) { source.size }
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
+ end
- 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)
+ context 'same as vector -ve size' do
+ let(:amount) { -source.size }
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
end
+
+ context 'positive' do
+ let(:amount) { 2 }
+ it { is_expected.to eq Daru::Vector.new([nil, nil, 1, 2, 3]) }
+ end
+
+ context 'negative' do
+ let(:amount) { -1 }
+ it { is_expected.to eq Daru::Vector.new([2, 3, 4, 5, nil]) }
+ end
+
+ context 'large positive' do
+ let(:amount) { source.size + 100 }
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
+ end
+
+ context 'large negative' do
+ let(:amount) { -(source.size + 100) }
+ it { is_expected.to eq Daru::Vector.new([nil]*source.size) }
+ end
+
end
-
+
context "#group_by" do
let(:dv) { Daru::Vector.new [:a, :b, :a, :b, :c] }
-
+
context 'vector not specified' do
- subject { dv.group_by }
-
+ subject { dv.group_by }
+
it { is_expected.to be_a Daru::Core::GroupBy }
its(:'groups.size') { is_expected.to eq 3 }
its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
end
-
+
context 'vector name specified' do
before { dv.name = :hello }
subject { dv.group_by :hello }
-
+
it { is_expected.to be_a Daru::Core::GroupBy }
its(:'groups.size') { is_expected.to eq 3 }
- its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
+ its(:groups) { is_expected.to eq({[:a]=>[0, 2], [:b]=>[1, 3], [:c]=>[4]}) }
end
-
+
context 'vector name invalid' do
before { dv.name = :hello }
it { expect { dv.group_by :abc }.to raise_error }
end
end
@@ -1972,10 +2095,28 @@
expect { vector.d = 5 }.to raise_error IndexError
end
end
end
+ context "#sort_by_index" do
+ let(:asc) { vector.sort_by_index }
+ let(:desc) { vector.sort_by_index(ascending: false) }
+
+ context 'numeric vector' do
+ let(:vector) { Daru::Vector.new [11, 13, 12], index: [23, 21, 22] }
+ specify { expect(asc.to_a).to eq [13, 12, 11] }
+ specify { expect(desc.to_a).to eq [11, 12, 13] }
+ end
+
+ context 'mix variable type index' do
+ let(:vector) { Daru::Vector.new [11, Float::NAN, nil],
+ index: [21, 23, 22] }
+ specify { expect(asc.to_a).to eq [11, nil, Float::NAN] }
+ specify { expect(desc.to_a).to eq [Float::NAN, nil, 11] }
+ end
+ end
+
context '#db_type' do
it 'is DATE for vector with any date in it' do
# FIXME: is it sane?.. - zverok
expect(Daru::Vector.new(['2016-03-01', 'foo', 4]).db_type).to eq 'DATE'
end
@@ -2001,6 +2142,15 @@
it 'should not accept anything else' do
expect { Daru::Vector.new([], dtype: :kittens) }.to raise_error(ArgumentError)
end
end
+ context '#where clause when Nan, nil data value is present' do
+ let(:v) { Daru::Vector.new([1,2,3,Float::NAN, nil]) }
+
+ it 'missing/undefined data in Vector/DataFrame' do
+ expect(v.where(v.lt(4))).to eq(Daru::Vector.new([1,2,3]))
+ expect(v.where(v.lt(3))).to eq(Daru::Vector.new([1,2]))
+ expect(v.where(v.lt(2))).to eq(Daru::Vector.new([1]))
+ end
+ end
end if mri?