object_table 0.2.8 → 0.3.0
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.
- checksums.yaml +8 -8
- data/README.md +13 -13
- data/lib/object_table.rb +15 -18
- data/lib/object_table/column.rb +7 -88
- data/lib/object_table/masked_column.rb +9 -2
- data/lib/object_table/table_methods.rb +1 -0
- data/lib/object_table/version.rb +1 -1
- data/spec/object_table/column_spec.rb +17 -234
- data/spec/object_table/grouped_spec.rb +1 -1
- data/spec/object_table/masked_column_spec.rb +70 -4
- data/spec/object_table_spec.rb +8 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTUwZmM3Nzk5N2I3NmE4ZGYwZmE0M2IzMjBkZDEyZTk0NTcxNzliNQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ODg5Zjc3Nzk5ZGIyMjk1OWNjYjFlYzhjMzhlMGNlNzdjMGI3ZWE0OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OWFlMzcwN2U2MTQ4Y2ZkNWQyY2I2Y2I1YWFkM2ZjMDIzNTgzYTAxOTNhZDVl
|
10
|
+
NmIxMDRkY2I0NjQ3NTAwZGYxYzU3MjRiZGFkMjU5ODg2ODdjNzBmMjEwNGNh
|
11
|
+
ZTRmODBiOWRiM2Y2Zjc5ZjY3OWYwZTk4YzgxY2UzZDdkY2YyMDI=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjkwZWRiM2FlYmVhNjgyNzRhYmZmN2I1YzVhYzJjYTVlYzVlMDFmZTFiNGM0
|
14
|
+
NjcyMzdlYTIwMDM2MjljN2VkNmM2OTM1MzBjOWZiOWJiMTlhYmE5MWQxMTI2
|
15
|
+
YmQxMmYxNzQ2MjhjMTc4ZTk3ODhhYTcyZTM2OGE4ZjMwOTNkNDY=
|
data/README.md
CHANGED
@@ -79,12 +79,12 @@ You can get a column by using `#[]` or using the column name as a method.
|
|
79
79
|
|
80
80
|
# using a method
|
81
81
|
>>> data.a
|
82
|
-
=>
|
82
|
+
=> NArray.int(3):
|
83
83
|
[ 1, 2, 3 ]
|
84
84
|
|
85
85
|
# ... or using []
|
86
86
|
>>> data[:a]
|
87
|
-
=>
|
87
|
+
=> NArray.int(3):
|
88
88
|
[ 1, 2, 3 ]
|
89
89
|
```
|
90
90
|
|
@@ -140,24 +140,24 @@ IndexError: dst.shape[0]=3 != src.shape[0]=4
|
|
140
140
|
>>> data = ObjectTable.new(col0: [0]*3)
|
141
141
|
>>> data[:col1] = [1, 2, 3]
|
142
142
|
>>> data.col1
|
143
|
-
=>
|
143
|
+
=> NArray.int(3):
|
144
144
|
[ 1, 2, 3 ]
|
145
145
|
|
146
146
|
# this time, let's make it a float instead
|
147
147
|
>>> data.set_column(:col2, [1, 2, 3], 'float')
|
148
148
|
>>> data.col2
|
149
|
-
=>
|
149
|
+
=> NArray.float(3):
|
150
150
|
[ 1.0, 2.0, 3.0 ]
|
151
151
|
|
152
152
|
>>> data[:col3] = 4
|
153
153
|
>>> data.col3
|
154
|
-
=>
|
154
|
+
=> NArray.object(3):
|
155
155
|
[ 4, 4, 4 ]
|
156
156
|
|
157
157
|
# this time, let's make it multi dimensional
|
158
158
|
>>> data.set_column(:col4, 4, 'int', 5)
|
159
159
|
>>> data.col4
|
160
|
-
=>
|
160
|
+
=> NArray.int(5,3):
|
161
161
|
[ [ 4, 4, 4, 4, 4 ],
|
162
162
|
[ 4, 4, 4, 4, 4 ],
|
163
163
|
[ 4, 4, 4, 4, 4 ] ]
|
@@ -166,12 +166,12 @@ IndexError: dst.shape[0]=3 != src.shape[0]=4
|
|
166
166
|
### Operating on columns
|
167
167
|
|
168
168
|
All standard NArray operations apply (addition, subtraction etc.)
|
169
|
-
Missing methods are vectorised over the column
|
169
|
+
Missing methods are vectorised over the column. (NOTE: this feature has been removed in v0.3.0)
|
170
170
|
|
171
171
|
```ruby
|
172
172
|
>>> data = ObjectTable.new(column: ['abc', 'bcd', 'cde'])
|
173
173
|
>>> data.column.match(/bc/)
|
174
|
-
=>
|
174
|
+
=> NArray.object(3):
|
175
175
|
[ #<MatchData "bc">, #<MatchData "bc">, nil ]
|
176
176
|
```
|
177
177
|
|
@@ -184,7 +184,7 @@ This is just a convenience method.
|
|
184
184
|
|
185
185
|
# this is exactly the same as (data.a + data.b)
|
186
186
|
>>> data.apply{ a + b }
|
187
|
-
=>
|
187
|
+
=> NArray.int(3):
|
188
188
|
[ 5, 7, 9 ]
|
189
189
|
|
190
190
|
# you can use self to set/add columns
|
@@ -199,7 +199,7 @@ This is just a convenience method.
|
|
199
199
|
|
200
200
|
# if you don't want it to steal the binding (self), make the block take an argument
|
201
201
|
>>> data.apply{|tbl| tbl.a + tbl.c }
|
202
|
-
=>
|
202
|
+
=> NArray.int(3):
|
203
203
|
[ 5, 12, 21 ]
|
204
204
|
```
|
205
205
|
|
@@ -468,7 +468,7 @@ The act of subclassing itself is easy, but any methods you add won't be availabl
|
|
468
468
|
|
469
469
|
>>> data = BrokenTable.new(a: 1..3, b: 4..6)
|
470
470
|
>>> data.a_plus_b
|
471
|
-
=>
|
471
|
+
=> NArray.int(3):
|
472
472
|
[ 5, 7, 9 ]
|
473
473
|
|
474
474
|
# this won't work!
|
@@ -498,12 +498,12 @@ The easiest way is just to include a module with your common methods.
|
|
498
498
|
|
499
499
|
>>> data = WorkingTable.new(a: 1..3, b: 4..6)
|
500
500
|
>>> data.a_plus_b
|
501
|
-
=>
|
501
|
+
=> NArray.int(3):
|
502
502
|
[ 5, 7, 9 ]
|
503
503
|
|
504
504
|
# hurrah!
|
505
505
|
>>> data.where{ a > 1 }.a_plus_b
|
506
|
-
=>
|
506
|
+
=> NArray.int(2):
|
507
507
|
[ 7, 9 ]
|
508
508
|
|
509
509
|
# also works in groups!
|
data/lib/object_table.rb
CHANGED
@@ -21,12 +21,12 @@ class ObjectTable
|
|
21
21
|
@columns = columns
|
22
22
|
|
23
23
|
@columns.each do |k, v|
|
24
|
-
@columns[k] =
|
24
|
+
@columns[k] = NArray.to_na(v)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
def add_column(name, typecode='object', *args)
|
29
|
-
col =
|
29
|
+
col = NArray.new(typecode, *args, nrows)
|
30
30
|
columns[name] = col
|
31
31
|
end
|
32
32
|
|
@@ -55,7 +55,7 @@ class ObjectTable
|
|
55
55
|
return self if new_values.values.first.empty?
|
56
56
|
|
57
57
|
new_values.each do |k, v|
|
58
|
-
@columns[k] = @columns[k]
|
58
|
+
@columns[k] = ObjectTable::Column.stack(@columns[k], *v)
|
59
59
|
end
|
60
60
|
self
|
61
61
|
end
|
@@ -123,20 +123,17 @@ class ObjectTable
|
|
123
123
|
lblank = lindex.eq(-1)
|
124
124
|
rblank = rindex.eq(-1)
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
col = col[*padding, rindex]
|
138
|
-
col[*padding, rblank] = [nil]
|
139
|
-
[k, col]
|
126
|
+
data = [
|
127
|
+
[left_cols, lindex, lblank, self],
|
128
|
+
[right_cols, rindex, rblank, other],
|
129
|
+
].flat_map do |cols, index, blanks, table|
|
130
|
+
cols.map do |k|
|
131
|
+
col = table.get_column(k)
|
132
|
+
padding = [nil] * (col.rank - 1)
|
133
|
+
col = col[*padding, index]
|
134
|
+
col[*padding, blanks] = [nil]
|
135
|
+
[k, col]
|
136
|
+
end
|
140
137
|
end
|
141
138
|
|
142
139
|
keys = []
|
@@ -150,7 +147,7 @@ class ObjectTable
|
|
150
147
|
end
|
151
148
|
end
|
152
149
|
|
153
|
-
self.class.new(keys +
|
150
|
+
self.class.new(keys + data)
|
154
151
|
end
|
155
152
|
|
156
153
|
|
data/lib/object_table/column.rb
CHANGED
@@ -1,97 +1,16 @@
|
|
1
1
|
require 'narray'
|
2
2
|
|
3
|
-
|
3
|
+
module ObjectTable::Column
|
4
4
|
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
value
|
9
|
-
when NArray
|
10
|
-
if value.rank <= 0
|
11
|
-
self.new(value.typecode, 0)
|
12
|
-
else
|
13
|
-
cast(value)
|
14
|
-
end
|
15
|
-
when Range
|
16
|
-
to_na(value.to_a)
|
17
|
-
when Array
|
18
|
-
to_na(value)
|
19
|
-
else
|
20
|
-
raise ArgumentError.new("Expected NArray or Array, got #{value.class}")
|
21
|
-
end
|
22
|
-
value
|
23
|
-
end
|
24
|
-
|
25
|
-
def slice(*)
|
26
|
-
self.class.make super
|
27
|
-
end
|
28
|
-
|
29
|
-
def [](*a)
|
30
|
-
result = super
|
31
|
-
result.is_a?(NArray) ? self.class.make(result) : result
|
32
|
-
end
|
33
|
-
|
34
|
-
def []=(*args)
|
35
|
-
if (args[-1].is_a?(Array) or args[-1].is_a?(NArray)) and args[-1].empty? and self.empty?
|
36
|
-
return args[-1]
|
37
|
-
end
|
38
|
-
|
39
|
-
super
|
40
|
-
end
|
41
|
-
|
42
|
-
def to_object
|
43
|
-
to_type('object')
|
44
|
-
end
|
45
|
-
|
46
|
-
def to_bool
|
47
|
-
map{|i| i ? 1 : 0}.to_type('byte')
|
48
|
-
end
|
49
|
-
|
50
|
-
def uniq
|
51
|
-
self.class.make to_a.uniq
|
52
|
-
end
|
53
|
-
|
54
|
-
def coerce_rev(other, operator)
|
55
|
-
other.send(operator, NArray.refer(self))
|
56
|
-
end
|
57
|
-
|
58
|
-
def method_missing(*args)
|
59
|
-
collect{|x| x.send(*args)}
|
60
|
-
end
|
61
|
-
|
62
|
-
# def collect(*)
|
63
|
-
# self.class.make super, name
|
64
|
-
# end
|
65
|
-
|
66
|
-
def _refer(value)
|
67
|
-
value.is_a?(NArray) ? NArray.refer(value) : value
|
68
|
-
end
|
69
|
-
|
70
|
-
%w{ + - * / }.each do |op|
|
71
|
-
define_method(op) do |other|
|
72
|
-
#self.class.make super(_refer(other)), name
|
73
|
-
super(_refer(other))
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
%w{ xor or and <= >= le ge < > gt lt % ** ne eq & | ^ to_type }.each do |op|
|
78
|
-
define_method(op) do |other|
|
79
|
-
self.class.make super(other)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# %w{ not abs -@ ~ }.each do |op|
|
84
|
-
# define_method(op) do
|
85
|
-
# self.class.make super()
|
86
|
-
# # end
|
87
|
-
# end
|
5
|
+
def self.stack(*columns)
|
6
|
+
return NArray[] if columns.empty?
|
7
|
+
return columns[0].clone if columns.length == 1
|
88
8
|
|
89
|
-
def stack(*others)
|
90
|
-
columns = [self] + others
|
91
9
|
new_rows = columns.map{|x| x.shape[-1]}.reduce(:+)
|
92
|
-
|
10
|
+
first_col = columns.first
|
11
|
+
new_col = NArray.new(first_col.typecode, *first_col.shape[0...-1], new_rows)
|
93
12
|
|
94
|
-
padding = [nil] * (rank - 1)
|
13
|
+
padding = [nil] * (first_col.rank - 1)
|
95
14
|
|
96
15
|
row = 0
|
97
16
|
columns.each do |col|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require_relative 'column'
|
2
2
|
|
3
|
-
class ObjectTable::MaskedColumn <
|
3
|
+
class ObjectTable::MaskedColumn < NArray
|
4
4
|
attr_accessor :indices, :parent, :padded_dims
|
5
5
|
|
6
|
+
EMPTY = NArray[]
|
7
|
+
|
6
8
|
def self.mask(parent, indices)
|
7
9
|
if parent.rank > 1
|
8
10
|
padded_dims = [nil] * (parent.rank - 1)
|
@@ -48,7 +50,12 @@ class ObjectTable::MaskedColumn < ObjectTable::Column
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def clone
|
51
|
-
|
53
|
+
NArray.cast(self).clone
|
54
|
+
end
|
55
|
+
|
56
|
+
def coerce_rev(other, operator)
|
57
|
+
return other.send(operator, EMPTY) if empty?
|
58
|
+
other.send(operator, NArray.cast(self))
|
52
59
|
end
|
53
60
|
|
54
61
|
end
|
data/lib/object_table/version.rb
CHANGED
@@ -1,258 +1,41 @@
|
|
1
1
|
require 'object_table/column'
|
2
2
|
|
3
|
-
shared_examples 'a column coercer' do |value|
|
4
|
-
subject{ ObjectTable::Column.make(value) }
|
5
|
-
|
6
|
-
it "should convert #{value.class} into a column" do
|
7
|
-
expect(subject).to be_a ObjectTable::Column
|
8
|
-
expect(subject.to_a).to eql value.to_a
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
shared_examples 'a NArray' do |operator, options={}|
|
13
|
-
unary = options[:unary]
|
14
|
-
|
15
|
-
let(:x){ ObjectTable::Column.make(0..10) }
|
16
|
-
let(:y){ ObjectTable::Column.make(5..15) }
|
17
|
-
|
18
|
-
let(:x_na){ NArray.to_na((0..10).to_a) }
|
19
|
-
let(:y_na){ NArray.to_na((5..15).to_a) }
|
20
|
-
|
21
|
-
if unary
|
22
|
-
subject{ x.send(operator) }
|
23
|
-
let(:expected_result){ x_na.send(operator) }
|
24
|
-
else
|
25
|
-
subject{ x.send(operator, y) }
|
26
|
-
let(:expected_result){ x_na.send(operator, y_na) }
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "#{operator}" do
|
30
|
-
it "should give the correct result" do
|
31
|
-
expect(subject).to eq expected_result
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'should return a column' do
|
35
|
-
expect(subject).to be_a ObjectTable::Column
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
shared_examples 'NArray slicing' do |is_column, *args|
|
41
|
-
let(:x_na) { NArray.to_na(x.to_a) }
|
42
|
-
|
43
|
-
%w{ [] slice }.each do |method|
|
44
|
-
describe "##{method}" do
|
45
|
-
let(:result) { x.send(method, *args) }
|
46
|
-
let(:expected_result) { x_na.send(method, *args) }
|
47
|
-
|
48
|
-
it "should give the correct result" do
|
49
|
-
expect(result).to eq expected_result
|
50
|
-
end
|
51
|
-
|
52
|
-
if is_column
|
53
|
-
it 'should return a column' do
|
54
|
-
expect(result).to be_a ObjectTable::Column
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
shared_examples 'a vectorized operator' do |method|
|
63
|
-
it "should vectorize :#{method} over the array" do
|
64
|
-
expect(subject.send(method).to_a).to eql subject.to_a.map{|x| x.send(method)}
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
3
|
describe ObjectTable::Column do
|
69
4
|
|
70
|
-
describe '.
|
71
|
-
subject{ ObjectTable::Column.make(value) }
|
72
|
-
|
73
|
-
context 'on a Column' do
|
74
|
-
let(:value){ ObjectTable::Column[1, 2, 3] }
|
75
|
-
|
76
|
-
it 'should return the same column' do
|
77
|
-
expect(subject).to be value
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
it_behaves_like "a column coercer", NArray[1, 2, 3]
|
82
|
-
it_behaves_like "a column coercer", 0...100
|
83
|
-
it_behaves_like "a column coercer", [1, 2, 3]
|
84
|
-
|
85
|
-
context 'on something unsupported' do
|
86
|
-
let(:value){ Object.new }
|
87
|
-
|
88
|
-
it 'should fail' do
|
89
|
-
expect{subject}.to raise_error
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
|
95
|
-
describe '#to_object' do
|
96
|
-
let(:column){ ObjectTable::Column[1, 2, 3] }
|
97
|
-
|
98
|
-
it 'should coerce the column into objects' do
|
99
|
-
expect(column.typecode).to eql NArray.int(0).typecode
|
100
|
-
expect(column.to_object.typecode).to eql NArray.object(0).typecode
|
101
|
-
expect(column.to_object).to eq column
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
describe '#to_bool' do
|
106
|
-
let(:column){ ObjectTable::Column.cast([true, false, nil, 'abcd', 1234], 'object') }
|
107
|
-
|
108
|
-
it 'should coerce the column into objects' do
|
109
|
-
expect(column.typecode).to eql NArray.object(0).typecode
|
110
|
-
expect(column.to_bool.typecode).to eql NArray.byte(0).typecode
|
111
|
-
expect(column.to_bool).to eq column.map{|i| i ? 1 : 0}
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe '#uniq' do
|
116
|
-
subject{ ObjectTable::Column.make([1, 1, 2, 2, 3, 1]) }
|
117
|
-
|
118
|
-
it 'should return a column of unique elements' do
|
119
|
-
expect(subject.uniq).to be_a ObjectTable::Column
|
120
|
-
expect(subject.uniq.to_a).to eql subject.to_a.uniq
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
describe 'vectorisation' do
|
126
|
-
subject{ ObjectTable::Column.make(Date.today ... (Date.today+100)) }
|
127
|
-
|
128
|
-
it_behaves_like 'a vectorized operator', 'day'
|
129
|
-
it_behaves_like 'a vectorized operator', 'month'
|
130
|
-
it_behaves_like 'a vectorized operator', 'year'
|
131
|
-
end
|
132
|
-
|
133
|
-
describe 'operations' do
|
134
|
-
it_behaves_like 'a NArray', '*'
|
135
|
-
it_behaves_like 'a NArray', '+'
|
136
|
-
it_behaves_like 'a NArray', '/'
|
137
|
-
it_behaves_like 'a NArray', '-'
|
138
|
-
it_behaves_like 'a NArray', '%'
|
139
|
-
it_behaves_like 'a NArray', '**'
|
140
|
-
it_behaves_like 'a NArray', '&'
|
141
|
-
it_behaves_like 'a NArray', '|'
|
142
|
-
it_behaves_like 'a NArray', '^'
|
143
|
-
it_behaves_like 'a NArray', 'eq'
|
144
|
-
it_behaves_like 'a NArray', 'ne'
|
145
|
-
it_behaves_like 'a NArray', 'gt'
|
146
|
-
it_behaves_like 'a NArray', '>'
|
147
|
-
it_behaves_like 'a NArray', 'ge'
|
148
|
-
it_behaves_like 'a NArray', '>='
|
149
|
-
it_behaves_like 'a NArray', 'lt'
|
150
|
-
it_behaves_like 'a NArray', '<'
|
151
|
-
it_behaves_like 'a NArray', 'le'
|
152
|
-
it_behaves_like 'a NArray', '<='
|
153
|
-
it_behaves_like 'a NArray', 'and'
|
154
|
-
it_behaves_like 'a NArray', 'or'
|
155
|
-
it_behaves_like 'a NArray', 'xor'
|
156
|
-
it_behaves_like 'a NArray', 'to_type'
|
157
|
-
|
158
|
-
it_behaves_like 'a NArray', '~', unary: true
|
159
|
-
it_behaves_like 'a NArray', '-@', unary: true
|
160
|
-
it_behaves_like 'a NArray', 'abs', unary: true
|
161
|
-
it_behaves_like 'a NArray', 'not', unary: true
|
162
|
-
|
163
|
-
end
|
164
|
-
|
165
|
-
describe 'slicing' do
|
166
|
-
let(:x){ ObjectTable::Column.float(10, 10, 10).random! }
|
167
|
-
|
168
|
-
it_behaves_like 'NArray slicing', false, 0
|
169
|
-
it_behaves_like 'NArray slicing', true, nil
|
170
|
-
it_behaves_like 'NArray slicing', false, 1, 2, 3
|
171
|
-
it_behaves_like 'NArray slicing', true, nil, nil, 5
|
172
|
-
it_behaves_like 'NArray slicing', true, nil, 5, 5
|
173
|
-
it_behaves_like 'NArray slicing', true, nil, true, false
|
174
|
-
it_behaves_like 'NArray slicing', true, [1, 2, 3, 4], nil, nil
|
175
|
-
it_behaves_like 'NArray slicing', true, [1, 2, 3, 4], nil, [1, 2]
|
176
|
-
it_behaves_like 'NArray slicing', true, 3...6
|
177
|
-
it_behaves_like 'NArray slicing', true, nil, nil, 3...6
|
178
|
-
it_behaves_like 'NArray slicing', true, 6...3, nil, 3...6
|
179
|
-
it_behaves_like 'NArray slicing', true, NArray[1..10] > 5, nil, nil
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "#mask" do
|
183
|
-
let(:x) { ObjectTable::Column.float(10, 10, 10).random! }
|
184
|
-
let(:mask) { x < 0.5 }
|
185
|
-
|
186
|
-
let(:expected_result) { NArray.to_na(x.to_a)[mask] }
|
187
|
-
|
188
|
-
subject{ x.mask(mask) }
|
189
|
-
|
190
|
-
it "should give the correct result" do
|
191
|
-
expect(subject).to eq expected_result
|
192
|
-
end
|
193
|
-
|
194
|
-
it 'should return a column' do
|
195
|
-
expect(subject).to be_a ObjectTable::Column
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
context 'when empty' do
|
200
|
-
let(:col) { ObjectTable::Column.float(0) }
|
201
|
-
|
202
|
-
describe '#[]=' do
|
203
|
-
context 'on an empty array' do
|
204
|
-
subject{ col[] = [] }
|
205
|
-
|
206
|
-
it 'should work' do
|
207
|
-
expect{subject}.to_not raise_error
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
context 'on an empty narray' do
|
212
|
-
subject{ col[] = NArray[] }
|
213
|
-
|
214
|
-
it 'should work' do
|
215
|
-
expect{subject}.to_not raise_error
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context 'on anything else' do
|
220
|
-
subject{ col[] = 3 }
|
221
|
-
|
222
|
-
it 'should not work' do
|
223
|
-
expect{subject}.to raise_error
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
end
|
228
|
-
end
|
229
|
-
|
230
|
-
describe '#stack' do
|
5
|
+
describe '.stack' do
|
231
6
|
let(:columns) do
|
232
7
|
[
|
233
|
-
|
8
|
+
NArray.float(10, 10).random!,
|
234
9
|
NArray.float(10, 30).random!,
|
235
|
-
|
10
|
+
NArray.to_na([[100] * 10] * 5),
|
236
11
|
]
|
237
12
|
end
|
238
13
|
|
239
|
-
subject{
|
14
|
+
subject{ ObjectTable::Column.stack(*columns) }
|
240
15
|
|
241
|
-
it 'should return a
|
242
|
-
expect(subject).to be_a
|
16
|
+
it 'should return a narray in the correct format' do
|
17
|
+
expect(subject).to be_a NArray
|
243
18
|
expect(subject.typecode).to eql columns[0].typecode
|
244
19
|
end
|
245
20
|
|
246
|
-
it 'should return a
|
21
|
+
it 'should return a narray with the correct size' do
|
247
22
|
expect(subject.shape[0...-1]).to eql columns[0].shape[0...-1]
|
248
23
|
expect(subject.shape[-1]).to eql (10 + 30 + 5)
|
249
24
|
end
|
250
25
|
|
251
|
-
it 'should stack the
|
26
|
+
it 'should stack the narrays' do
|
252
27
|
expect(subject[nil, 0...10]).to eq columns[0]
|
253
28
|
expect(subject[nil, 10...40]).to eq columns[1]
|
254
29
|
expect(subject[nil, 40...45]).to eq columns[2]
|
255
30
|
end
|
31
|
+
|
32
|
+
context 'with no arguments' do
|
33
|
+
let(:columns) { [] }
|
34
|
+
|
35
|
+
it 'should return an empty NArray' do
|
36
|
+
expect(subject).to eq NArray[]
|
37
|
+
end
|
38
|
+
end
|
256
39
|
end
|
257
40
|
|
258
|
-
end
|
41
|
+
end
|
@@ -1,8 +1,42 @@
|
|
1
1
|
require 'object_table/masked_column'
|
2
2
|
|
3
|
+
shared_examples 'a NArray' do |operator, options={}|
|
4
|
+
unary = options[:unary]
|
5
|
+
|
6
|
+
let(:indices) { NArray[1, 3, 4, 6] }
|
7
|
+
|
8
|
+
let(:x){ ObjectTable::MaskedColumn.mask(x_na, indices) }
|
9
|
+
let(:y){ ObjectTable::MaskedColumn.mask(y_na, indices) }
|
10
|
+
|
11
|
+
let(:x_na){ NArray.to_na((0..10).to_a) }
|
12
|
+
let(:y_na){ NArray.to_na((5..15).to_a) }
|
13
|
+
|
14
|
+
if unary
|
15
|
+
subject{ x.send(operator) }
|
16
|
+
let(:expected_result){ x_na[indices].send(operator) }
|
17
|
+
else
|
18
|
+
subject{ x.send(operator, y) }
|
19
|
+
let(:expected_result){ x_na.send(operator, y_na)[indices] }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#{operator}" do
|
23
|
+
it "should give the correct result" do
|
24
|
+
expect(subject).to eq expected_result
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with empty indices' do
|
28
|
+
let(:indices) { [] }
|
29
|
+
|
30
|
+
it "should give the correct result" do
|
31
|
+
expect(subject).to eq expected_result
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
3
37
|
describe ObjectTable::MaskedColumn do
|
4
38
|
|
5
|
-
let(:parent) {
|
39
|
+
let(:parent) { NArray.float(10).random! }
|
6
40
|
let(:indices) { NArray[1, 3, 4, 6] }
|
7
41
|
let(:other_indices) { NArray.to_na((0...parent.length).to_a - indices.to_a) }
|
8
42
|
let(:masked) { ObjectTable::MaskedColumn.mask(parent, indices) }
|
@@ -118,7 +152,7 @@ describe ObjectTable::MaskedColumn do
|
|
118
152
|
end
|
119
153
|
|
120
154
|
context 'with complex numbers' do
|
121
|
-
let(:parent) {
|
155
|
+
let(:parent) { NArray.complex(10).indgen! }
|
122
156
|
|
123
157
|
include_examples 'destructive methods', 'imag=', 56
|
124
158
|
include_examples 'destructive methods', 'conj!'
|
@@ -127,8 +161,8 @@ describe ObjectTable::MaskedColumn do
|
|
127
161
|
describe '#clone' do
|
128
162
|
let(:clone){ subject.clone }
|
129
163
|
|
130
|
-
it 'returns a
|
131
|
-
expect(clone).to be_an_instance_of
|
164
|
+
it 'returns a NArray' do
|
165
|
+
expect(clone).to be_an_instance_of NArray
|
132
166
|
expect(clone).to_not be_an_instance_of ObjectTable::MaskedColumn
|
133
167
|
end
|
134
168
|
|
@@ -137,4 +171,36 @@ describe ObjectTable::MaskedColumn do
|
|
137
171
|
end
|
138
172
|
end
|
139
173
|
|
174
|
+
describe 'operations' do
|
175
|
+
it_behaves_like 'a NArray', '*'
|
176
|
+
it_behaves_like 'a NArray', '+'
|
177
|
+
it_behaves_like 'a NArray', '/'
|
178
|
+
it_behaves_like 'a NArray', '-'
|
179
|
+
it_behaves_like 'a NArray', '%'
|
180
|
+
it_behaves_like 'a NArray', '**'
|
181
|
+
it_behaves_like 'a NArray', '&'
|
182
|
+
it_behaves_like 'a NArray', '|'
|
183
|
+
it_behaves_like 'a NArray', '^'
|
184
|
+
it_behaves_like 'a NArray', 'eq'
|
185
|
+
it_behaves_like 'a NArray', 'ne'
|
186
|
+
it_behaves_like 'a NArray', 'gt'
|
187
|
+
it_behaves_like 'a NArray', '>'
|
188
|
+
it_behaves_like 'a NArray', 'ge'
|
189
|
+
it_behaves_like 'a NArray', '>='
|
190
|
+
it_behaves_like 'a NArray', 'lt'
|
191
|
+
it_behaves_like 'a NArray', '<'
|
192
|
+
it_behaves_like 'a NArray', 'le'
|
193
|
+
it_behaves_like 'a NArray', '<='
|
194
|
+
it_behaves_like 'a NArray', 'and'
|
195
|
+
it_behaves_like 'a NArray', 'or'
|
196
|
+
it_behaves_like 'a NArray', 'xor'
|
197
|
+
it_behaves_like 'a NArray', 'to_type'
|
198
|
+
|
199
|
+
it_behaves_like 'a NArray', '~', unary: true
|
200
|
+
it_behaves_like 'a NArray', '-@', unary: true
|
201
|
+
it_behaves_like 'a NArray', 'abs', unary: true
|
202
|
+
it_behaves_like 'a NArray', 'not', unary: true
|
203
|
+
end
|
204
|
+
|
205
|
+
|
140
206
|
end
|
data/spec/object_table_spec.rb
CHANGED
@@ -9,9 +9,9 @@ describe ObjectTable do
|
|
9
9
|
let(:columns){ {col1: [1, 2, 3], col2: NArray[4, 5, 6], col3: 7..9, col4: 10} }
|
10
10
|
subject{ ObjectTable.new columns }
|
11
11
|
|
12
|
-
it 'should convert all columns into
|
12
|
+
it 'should convert all columns into NArrays' do
|
13
13
|
subject.columns.values.each do |v|
|
14
|
-
expect(v).to be_a
|
14
|
+
expect(v).to be_a NArray
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -25,11 +25,11 @@ describe ObjectTable do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
context 'with multi dimensional columns' do
|
28
|
-
let(:columns){ {col1: [1, 2, 3], col2:
|
28
|
+
let(:columns){ {col1: [1, 2, 3], col2: [[4, 4], [5, 5], [6, 6]]} }
|
29
29
|
|
30
|
-
it 'should convert all columns into
|
30
|
+
it 'should convert all columns into NArrays' do
|
31
31
|
subject.columns.values.each do |v|
|
32
|
-
expect(v).to be_a
|
32
|
+
expect(v).to be_a NArray
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -43,7 +43,7 @@ describe ObjectTable do
|
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'should preserve the dimensions' do
|
46
|
-
expect(subject[:col2].shape).to eql columns[:col2].shape
|
46
|
+
expect(subject[:col2].shape).to eql NArray.to_na(columns[:col2]).shape
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -81,9 +81,9 @@ describe ObjectTable do
|
|
81
81
|
expect(table.columns[column].to_a).to eql value
|
82
82
|
end
|
83
83
|
|
84
|
-
it 'should coerce the value to a
|
84
|
+
it 'should coerce the value to a narray' do
|
85
85
|
subject
|
86
|
-
expect(table.columns[column]).to be_a
|
86
|
+
expect(table.columns[column]).to be_a NArray
|
87
87
|
end
|
88
88
|
|
89
89
|
context 'with the wrong length' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object_table
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cheney Lin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: narray
|