red_amber 0.2.2 → 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 +4 -4
- data/.rubocop.yml +114 -39
- data/CHANGELOG.md +203 -31
- data/Gemfile +5 -2
- data/README.md +62 -29
- data/benchmark/basic.yml +86 -0
- data/benchmark/combine.yml +62 -0
- data/benchmark/dataframe.yml +62 -0
- data/benchmark/drop_nil.yml +15 -3
- data/benchmark/group.yml +39 -0
- data/benchmark/reshape.yml +31 -0
- data/benchmark/{csv_load_penguins.yml → rover/csv_load_penguins.yml} +3 -3
- data/benchmark/rover/flights.yml +23 -0
- data/benchmark/rover/penguins.yml +23 -0
- data/benchmark/rover/planes.yml +23 -0
- data/benchmark/rover/weather.yml +23 -0
- data/benchmark/vector.yml +60 -0
- data/doc/DataFrame.md +335 -53
- data/doc/Vector.md +91 -0
- data/doc/image/dataframe/join.png +0 -0
- data/doc/image/dataframe/set_and_bind.png +0 -0
- data/doc/image/dataframe_model.png +0 -0
- data/lib/red_amber/data_frame.rb +167 -51
- data/lib/red_amber/data_frame_combinable.rb +486 -0
- data/lib/red_amber/data_frame_displayable.rb +6 -4
- data/lib/red_amber/data_frame_indexable.rb +2 -2
- data/lib/red_amber/data_frame_loadsave.rb +4 -1
- data/lib/red_amber/data_frame_reshaping.rb +35 -10
- data/lib/red_amber/data_frame_selectable.rb +221 -116
- data/lib/red_amber/data_frame_variable_operation.rb +146 -82
- data/lib/red_amber/group.rb +108 -18
- data/lib/red_amber/helper.rb +53 -43
- data/lib/red_amber/refinements.rb +199 -0
- data/lib/red_amber/vector.rb +56 -46
- data/lib/red_amber/vector_functions.rb +23 -83
- data/lib/red_amber/vector_selectable.rb +116 -69
- data/lib/red_amber/vector_updatable.rb +189 -65
- data/lib/red_amber/version.rb +1 -1
- data/lib/red_amber.rb +3 -0
- data/red_amber.gemspec +4 -3
- metadata +24 -10
@@ -4,91 +4,122 @@
|
|
4
4
|
# reference: https://arrow.apache.org/docs/cpp/compute.html
|
5
5
|
|
6
6
|
module RedAmber
|
7
|
-
# mix-
|
8
|
-
#
|
7
|
+
# mix-in for class Vector
|
8
|
+
# Functions to select some data.
|
9
9
|
module VectorSelectable
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
using RefineArray
|
11
|
+
using RefineArrayLike
|
12
|
+
|
13
|
+
# Select elements in the self by indices.
|
14
|
+
#
|
15
|
+
# @param indices [Array<Numeric>, Vector] indices.
|
16
|
+
# @yield [Array<Numeric>, Vector] indices.
|
17
|
+
# @return [Vector] Vector by selected elements.
|
18
|
+
#
|
19
|
+
# TODO: support for the option `boundscheck: true`
|
20
|
+
def take(*indices, &block)
|
21
|
+
if block
|
22
|
+
unless indices.empty?
|
23
|
+
raise VectorArgumentError, 'Must not specify both arguments and block.'
|
24
|
+
end
|
14
25
|
|
15
|
-
|
16
|
-
|
17
|
-
def take(*indices)
|
18
|
-
indices.flatten!
|
19
|
-
return Vector.new([]) if indices.empty?
|
26
|
+
indices = [yield]
|
27
|
+
end
|
20
28
|
|
21
|
-
|
22
|
-
|
29
|
+
vector =
|
30
|
+
case indices
|
31
|
+
in [Vector => v] if v.numeric?
|
32
|
+
return Vector.create(take_by_vector(v))
|
33
|
+
in []
|
34
|
+
return Vector.new
|
35
|
+
in [(Arrow::Array | Arrow::ChunkedArray) => aa]
|
36
|
+
Vector.create(aa)
|
37
|
+
else
|
38
|
+
Vector.new(indices.flatten)
|
39
|
+
end
|
23
40
|
|
24
|
-
|
41
|
+
unless vector.numeric?
|
42
|
+
raise VectorArgumentError, "argument must be a integers: #{indices}"
|
43
|
+
end
|
44
|
+
|
45
|
+
Vector.create(take_by_vector(vector))
|
25
46
|
end
|
26
47
|
|
27
|
-
#
|
48
|
+
# Select elements in the self by booleans.
|
49
|
+
#
|
50
|
+
# @param booleans [Array<true, false, nil>, Vector] booleans.
|
51
|
+
# @yield [Array<true, false, nil>, Vector] booleans.
|
52
|
+
# @return [Vector] Vector by selected elements.
|
53
|
+
#
|
54
|
+
# TODO: support for the option `null_selection_behavior: :drop`
|
28
55
|
def filter(*booleans, &block)
|
29
56
|
if block
|
30
|
-
|
57
|
+
unless booleans.empty?
|
58
|
+
raise VectorArgumentError, 'Must not specify both arguments and block.'
|
59
|
+
end
|
31
60
|
|
32
61
|
booleans = [yield]
|
33
62
|
end
|
34
63
|
|
35
|
-
booleans
|
36
|
-
|
37
|
-
|
38
|
-
b = booleans[0]
|
39
|
-
boolean_array =
|
40
|
-
case b
|
41
|
-
when Vector
|
42
|
-
raise VectorTypeError, 'Argument is not a boolean.' unless b.boolean?
|
64
|
+
case booleans
|
65
|
+
in [Vector => v]
|
66
|
+
raise VectorTypeError, 'Argument is not a boolean.' unless v.boolean?
|
43
67
|
|
44
|
-
|
45
|
-
|
46
|
-
|
68
|
+
Vector.create(filter_by_array(v.data))
|
69
|
+
in [Arrow::BooleanArray => ba]
|
70
|
+
Vector.create(filter_by_array(ba))
|
71
|
+
in []
|
72
|
+
Vector.new
|
73
|
+
else
|
74
|
+
booleans.flatten!
|
75
|
+
a = Arrow::Array.new(booleans)
|
76
|
+
if a.boolean?
|
77
|
+
Vector.create(filter_by_array(a))
|
78
|
+
elsif booleans.compact.empty? # [nil, nil] becomes string array
|
79
|
+
Vector.new
|
47
80
|
else
|
48
|
-
raise VectorTypeError,
|
49
|
-
|
50
|
-
Arrow::BooleanArray.new(booleans)
|
81
|
+
raise VectorTypeError, "Argument is not a boolean: #{booleans}"
|
51
82
|
end
|
52
|
-
|
53
|
-
filter_by_array(boolean_array) # returns sub Vector
|
83
|
+
end
|
54
84
|
end
|
55
85
|
alias_method :select, :filter
|
56
86
|
alias_method :find_all, :filter
|
57
87
|
|
58
|
-
#
|
59
|
-
#
|
88
|
+
# Select elements in the self by indices or booleans.
|
89
|
+
#
|
90
|
+
# @param args [Array<Numeric, true, false, nil>, Vector] specifier.
|
91
|
+
# @yield [Array<Numeric, true, false, nil>, Vector] specifier.
|
92
|
+
# @return [scalar, Array] returns scalar or array.
|
93
|
+
#
|
60
94
|
def [](*args)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
unless arg.is_a?(Numeric) || booleans?([arg])
|
79
|
-
raise VectorArgumentError, "Argument must be numeric or boolean: #{args}"
|
95
|
+
array =
|
96
|
+
case args
|
97
|
+
in [Vector => v]
|
98
|
+
return scalar_or_array(take_by_vector(v)) if v.numeric?
|
99
|
+
return scalar_or_array(filter_by_array(v.data)) if v.boolean?
|
100
|
+
|
101
|
+
raise VectorTypeError, "Argument must be numeric or boolean: #{args}"
|
102
|
+
in [Arrow::BooleanArray => ba]
|
103
|
+
return scalar_or_array(filter_by_array(ba))
|
104
|
+
in []
|
105
|
+
return nil
|
106
|
+
in [Arrow::Array => arrow_array]
|
107
|
+
arrow_array
|
108
|
+
in [Range => r]
|
109
|
+
Arrow::Array.new(parse_range(r, size))
|
110
|
+
else
|
111
|
+
Arrow::Array.new(args.flatten)
|
80
112
|
end
|
81
|
-
|
82
|
-
array
|
83
|
-
return filter_by_array(array) if array.is_a?(Arrow::BooleanArray)
|
113
|
+
|
114
|
+
return scalar_or_array(filter_by_array(array)) if array.boolean?
|
84
115
|
|
85
116
|
vector = Vector.new(array)
|
86
|
-
return take_by_vector(vector) if vector.numeric?
|
117
|
+
return scalar_or_array(take_by_vector(vector)) if vector.numeric?
|
87
118
|
|
88
119
|
raise VectorArgumentError, "Invalid argument: #{args}"
|
89
120
|
end
|
90
121
|
|
91
|
-
#
|
122
|
+
# @param values [Array, Arrow::Array, Vector]
|
92
123
|
def is_in(*values)
|
93
124
|
self_data = chunked? ? data.pack : data
|
94
125
|
|
@@ -100,7 +131,7 @@ module RedAmber
|
|
100
131
|
Array(values).flatten
|
101
132
|
end
|
102
133
|
|
103
|
-
Vector.
|
134
|
+
Vector.create(self_data.is_in(array))
|
104
135
|
end
|
105
136
|
|
106
137
|
# Arrow's support required
|
@@ -108,28 +139,44 @@ module RedAmber
|
|
108
139
|
to_a.index(element)
|
109
140
|
end
|
110
141
|
|
142
|
+
def drop_nil
|
143
|
+
datum = find(:drop_null).execute([data])
|
144
|
+
Vector.create(datum.value)
|
145
|
+
end
|
146
|
+
|
111
147
|
private
|
112
148
|
|
113
149
|
# Accepts indices by numeric Vector
|
114
150
|
def take_by_vector(indices)
|
115
|
-
|
116
|
-
raise VectorArgumentError, "Index out of range: #{indices.min}" if indices.min <= -size - 1
|
151
|
+
indices = (indices < 0).if_else(indices + size, indices) if (indices < 0).any?
|
117
152
|
|
118
|
-
|
119
|
-
raise VectorArgumentError, "Index out of range: #{
|
153
|
+
min, max = indices.min_max
|
154
|
+
raise VectorArgumentError, "Index out of range: #{min}" if min < 0
|
155
|
+
raise VectorArgumentError, "Index out of range: #{max}" if max >= size
|
120
156
|
|
121
|
-
index_array =
|
157
|
+
index_array =
|
158
|
+
if indices.float?
|
159
|
+
Arrow::UInt64ArrayBuilder.build(indices.data)
|
160
|
+
else
|
161
|
+
indices.data
|
162
|
+
end
|
122
163
|
|
123
|
-
|
124
|
-
|
164
|
+
# :array_take will fail with ChunkedArray
|
165
|
+
find(:take).execute([data, index_array]).value
|
125
166
|
end
|
126
167
|
|
127
168
|
# Accepts booleans by Arrow::BooleanArray
|
128
169
|
def filter_by_array(boolean_array)
|
129
|
-
|
170
|
+
unless boolean_array.length == size
|
171
|
+
raise VectorArgumentError, 'Booleans must be same size as self.'
|
172
|
+
end
|
173
|
+
|
174
|
+
find(:array_filter).execute([data, boolean_array]).value
|
175
|
+
end
|
130
176
|
|
131
|
-
|
132
|
-
|
177
|
+
def scalar_or_array(arrow_array)
|
178
|
+
a = arrow_array.to_a
|
179
|
+
a.size > 1 ? a : a[0]
|
133
180
|
end
|
134
181
|
end
|
135
182
|
end
|
@@ -4,41 +4,52 @@
|
|
4
4
|
# reference: https://arrow.apache.org/docs/cpp/compute.html
|
5
5
|
|
6
6
|
module RedAmber
|
7
|
-
# mix-
|
7
|
+
# mix-in for class Vector
|
8
8
|
# Functions to make up some data (especially missing) for new data.
|
9
9
|
module VectorUpdatable
|
10
|
+
# Add properties to Arrow::Array and Arrow::ChunkedArray
|
11
|
+
using RefineArrayLike
|
12
|
+
|
10
13
|
# Replace data
|
11
|
-
# @param
|
12
|
-
# @param replacer [Array, Vector, Arrow::Array] new data to replace for.
|
14
|
+
# @param specifier [Array, Vector, Arrow::Array] index or booleans.
|
15
|
+
# @param replacer [Scalar, Array, Vector, Arrow::Array] new data to replace for.
|
13
16
|
# @return [Vector] Replaced new Vector.
|
14
|
-
# If
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
args
|
20
|
-
when Range
|
21
|
-
normalize_element(args)
|
22
|
-
else
|
23
|
-
Array(args)
|
24
|
-
end
|
25
|
-
replacer = Array(replacer)
|
26
|
-
return self if args.empty? || args[0].nil?
|
17
|
+
# If specifier has no true, return self.
|
18
|
+
#
|
19
|
+
def replace(specifier, replacer)
|
20
|
+
vector = Vector.new(parse_args(Array(specifier), size))
|
21
|
+
return self if vector.empty? || empty?
|
27
22
|
|
28
|
-
vector = parse_to_vector(args)
|
29
|
-
replacer = nil if replacer.empty?
|
30
23
|
booleans =
|
31
24
|
if vector.boolean?
|
32
|
-
return self unless vector.any
|
33
|
-
|
34
25
|
vector
|
35
26
|
elsif vector.numeric?
|
36
|
-
replacer.sort_by! { |x| args[replacer.index(x)] } if replacer # rubocop:disable Style/SafeNavigation
|
37
27
|
Vector.new(indices).is_in(vector)
|
38
28
|
else
|
39
|
-
raise VectorArgumentError, "Invalid data type #{
|
29
|
+
raise VectorArgumentError, "Invalid data type #{specifier}"
|
30
|
+
end
|
31
|
+
return self if booleans.sum.zero?
|
32
|
+
|
33
|
+
replacer_array =
|
34
|
+
case replacer
|
35
|
+
in []
|
36
|
+
return self
|
37
|
+
in nil | [nil]
|
38
|
+
return replace_to_nil(booleans.data)
|
39
|
+
in Arrow::Array
|
40
|
+
# nop
|
41
|
+
in Vector
|
42
|
+
replacer.data
|
43
|
+
in Array
|
44
|
+
Arrow::Array.new(replacer)
|
45
|
+
else # Broadcast scalar to Array
|
46
|
+
Arrow::Array.new(Array(replacer) * booleans.to_a.count(true))
|
40
47
|
end
|
41
|
-
|
48
|
+
if booleans.sum != replacer_array.length
|
49
|
+
raise VectorArgumentError, 'Replacements size unmatch'
|
50
|
+
end
|
51
|
+
|
52
|
+
replace_with(booleans.data, replacer_array)
|
42
53
|
end
|
43
54
|
|
44
55
|
# (related functions)
|
@@ -51,7 +62,7 @@ module RedAmber
|
|
51
62
|
raise VectorTypeError, 'Reciever must be a boolean' unless boolean?
|
52
63
|
|
53
64
|
datum = find(:if_else).execute([data, true_choice, false_choice])
|
54
|
-
Vector.
|
65
|
+
Vector.create(datum.value)
|
55
66
|
end
|
56
67
|
|
57
68
|
# same behavior as Ruby's invert
|
@@ -74,55 +85,168 @@ module RedAmber
|
|
74
85
|
end
|
75
86
|
end
|
76
87
|
|
77
|
-
|
88
|
+
# Split string Vector and returns Array of columns.
|
89
|
+
#
|
90
|
+
# @param sep [nil, String, Regexp] separater.
|
91
|
+
# If separator is nil (or no argeument given), the column will be splitted by
|
92
|
+
# Arrow's split function using any ASCII whitespace.
|
93
|
+
# Otherwise sep will passed to String#split.
|
94
|
+
# @param limit [Integer] maximum number to limit separation. Passed to String#split.
|
95
|
+
# @return [Array<Vector>] an Array of Vectors.
|
96
|
+
# @note nil will separated as nil's at same row. ex) `nil => [nil, nil]`
|
97
|
+
#
|
98
|
+
def split_to_columns(sep = nil, limit = 0)
|
99
|
+
l = split(sep, limit)
|
100
|
+
l.list_separate
|
101
|
+
end
|
102
|
+
|
103
|
+
# Split string Vector and flatten into rows.
|
104
|
+
#
|
105
|
+
# @param sep [nil, String, Regexp] separater.
|
106
|
+
# If separator is nil (or no argeument given), the column will be splitted by
|
107
|
+
# Arrow's split function using any ASCII whitespace.
|
108
|
+
# Otherwise sep will passed to String#split.
|
109
|
+
# @param limit [Integer] maximum number to limit separation. Passed to String#split.
|
110
|
+
# @return [Vector] a flatten Vector.
|
111
|
+
# @note nil will separated as nil's at same row. ex) `nil => [nil, nil]`
|
112
|
+
#
|
113
|
+
def split_to_rows(sep = nil, limit = 0)
|
114
|
+
l = split(sep, limit)
|
115
|
+
l.list_flatten
|
116
|
+
end
|
117
|
+
|
118
|
+
# return element size Array for list Vector.
|
119
|
+
#
|
120
|
+
# @api private
|
121
|
+
#
|
122
|
+
def list_sizes
|
123
|
+
Vector.create find(:list_value_length).execute([data]).value
|
124
|
+
end
|
125
|
+
|
126
|
+
# Separate list Vector by columns.
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
#
|
130
|
+
def list_separate
|
131
|
+
len = list_sizes.data
|
132
|
+
min, max = Arrow::Function.find(:min_max).execute([len]).value.value.map(&:value)
|
133
|
+
|
134
|
+
result = []
|
135
|
+
(0...min).each do |i|
|
136
|
+
result << Vector.create(find(:list_element).execute([data, i]).value)
|
137
|
+
end
|
138
|
+
return result if min == max
|
139
|
+
|
140
|
+
(min...max).each do |i|
|
141
|
+
result << Vector.new(data.map { |e| e&.[](i) })
|
142
|
+
end
|
143
|
+
result
|
144
|
+
end
|
78
145
|
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
146
|
+
# Flatten list Vector for rows.
|
147
|
+
#
|
148
|
+
# @api private
|
149
|
+
#
|
150
|
+
def list_flatten
|
151
|
+
Vector.create find(:list_flatten).execute([data]).value
|
152
|
+
end
|
153
|
+
|
154
|
+
# Split string Vector by each element with separator and returns list Array.
|
155
|
+
#
|
156
|
+
# @note if sep is not specified, use Arrow's ascii_split_whitespace.
|
157
|
+
# It will separate string by ascii whitespaces.
|
158
|
+
# @note if sep specified, sep and limit will passed to String#split.
|
159
|
+
#
|
160
|
+
def split(sep = nil, limit = 0)
|
161
|
+
if empty? || !string?
|
162
|
+
raise VectorTypeError, "self is not a valid string Vector: #{self}"
|
163
|
+
end
|
164
|
+
if self[0].nil? && uniq.to_a == [nil] # Avoid heavy check to be activated always.
|
165
|
+
raise VectorTypeError, 'self contains only nil'
|
166
|
+
end
|
167
|
+
|
168
|
+
list =
|
169
|
+
if sep
|
170
|
+
Arrow::Array.new(to_a.map { |e| e&.split(sep, limit) })
|
98
171
|
else
|
99
|
-
|
172
|
+
find(:ascii_split_whitespace).execute([data]).value
|
100
173
|
end
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
174
|
+
Vector.create(list)
|
175
|
+
end
|
176
|
+
|
177
|
+
# Merge String or other string Vector to self.
|
178
|
+
# Self must be a string Vector.
|
179
|
+
#
|
180
|
+
# @param other [String, Vector]
|
181
|
+
# merger from right. It will be broadcasted if it is a scalar String.
|
182
|
+
# @param sep [String] separator.
|
183
|
+
# @return [Vector] merged Vector
|
184
|
+
#
|
185
|
+
def merge(other, sep: ' ')
|
186
|
+
if empty? || !string?
|
187
|
+
raise VectorTypeError,
|
188
|
+
"self is not a string Vector: #{self}"
|
189
|
+
end
|
190
|
+
unless sep.is_a?(String)
|
191
|
+
raise VectorArgumentError, "separator is not a String: #{sep}"
|
192
|
+
end
|
193
|
+
|
194
|
+
other_array =
|
195
|
+
case other
|
196
|
+
in String => s
|
197
|
+
[s] * size
|
198
|
+
in (Vector | Arrow::Array | Arrow::ChunkedArray) => x if x.string?
|
199
|
+
x.to_a
|
115
200
|
else
|
116
|
-
|
201
|
+
raise VectorArgumentError,
|
202
|
+
"other is not a String or a string Vector: #{self}"
|
117
203
|
end
|
118
|
-
replacer = data.class.new(replacer) if replacer.uniq == [nil]
|
119
204
|
|
120
|
-
|
205
|
+
list = Arrow::Array.new(to_a.zip(other_array))
|
206
|
+
datum = find(:binary_join).execute([list, sep])
|
207
|
+
Vector.create(datum.value)
|
208
|
+
end
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
# Replace elements selected with a boolean mask
|
213
|
+
#
|
214
|
+
# @param boolean_mask [Arrow::BooleanArray]
|
215
|
+
# Boolean mask which indicates the position to be replaced.
|
216
|
+
# - Position with true will be replaced.
|
217
|
+
# - Position with nil will be nil.
|
218
|
+
#
|
219
|
+
# @param replacer [Arrow::Array] Values after replaced
|
220
|
+
# (either scalar or array). If Array is given, original values are replaced by
|
221
|
+
# each element of the array at the corresponding position of mask element.
|
222
|
+
# - `replacer.size` must be equal to `mask.count(true)`.
|
223
|
+
# - Types of self and replacer must be same
|
224
|
+
#
|
225
|
+
# @return [Vector] Replaced vector.
|
226
|
+
# Type of returned Vector is upcasted if needed.
|
227
|
+
#
|
228
|
+
def replace_with(boolean_mask, replacer)
|
229
|
+
raise VectorArgumentError, 'Booleans size unmatch' if boolean_mask.length != size
|
230
|
+
raise VectorArgumentError, 'Booleans not have any `true`' unless boolean_mask.any?
|
231
|
+
|
232
|
+
values = replacer.class.new(data) # Upcast
|
121
233
|
|
122
|
-
|
234
|
+
datum = find(:replace_with_mask).execute([values, boolean_mask, replacer])
|
235
|
+
Vector.create(datum.value)
|
236
|
+
end
|
123
237
|
|
124
|
-
|
125
|
-
|
238
|
+
# Replace elements selected with a boolean mask by nil
|
239
|
+
#
|
240
|
+
# @param boolean_mask [Arrow::BooleanArray]
|
241
|
+
# Boolean mask which indicates the position to be replaced.
|
242
|
+
# - Position with true will be replaced by nil
|
243
|
+
# - Position with nil will remain as nil.
|
244
|
+
# @return [Vector] Replaced vector.
|
245
|
+
#
|
246
|
+
def replace_to_nil(boolean_mask)
|
247
|
+
nil_array = data.class.new([nil] * size) # Casted nil Array
|
248
|
+
datum = find(:if_else).execute([boolean_mask, nil_array, data])
|
249
|
+
Vector.create(datum.value)
|
126
250
|
end
|
127
251
|
end
|
128
252
|
end
|
data/lib/red_amber/version.rb
CHANGED
data/lib/red_amber.rb
CHANGED
@@ -2,7 +2,10 @@
|
|
2
2
|
|
3
3
|
require 'arrow'
|
4
4
|
|
5
|
+
require_relative 'red_amber/refinements'
|
5
6
|
require_relative 'red_amber/helper'
|
7
|
+
|
8
|
+
require_relative 'red_amber/data_frame_combinable'
|
6
9
|
require_relative 'red_amber/data_frame_displayable'
|
7
10
|
require_relative 'red_amber/data_frame_indexable'
|
8
11
|
require_relative 'red_amber/data_frame_loadsave'
|
data/red_amber.gemspec
CHANGED
@@ -9,10 +9,11 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = ['heronshoes877@gmail.com']
|
10
10
|
|
11
11
|
spec.summary = 'Simple dataframe library for Ruby'
|
12
|
-
spec.description = 'RedAmber is a simple dataframe library
|
12
|
+
spec.description = 'RedAmber is a simple dataframe library' \
|
13
|
+
'inspired by Rover-df and powered by Red Arrow.'
|
13
14
|
spec.homepage = 'https://github.com/heronshoes/red_amber'
|
14
15
|
spec.license = 'MIT'
|
15
|
-
spec.required_ruby_version = '>=
|
16
|
+
spec.required_ruby_version = '>= 3.0'
|
16
17
|
|
17
18
|
spec.metadata['homepage_uri'] = spec.homepage
|
18
19
|
spec.metadata['source_code_uri'] = 'https://github.com/heronshoes/red_amber'
|
@@ -30,7 +31,7 @@ Gem::Specification.new do |spec|
|
|
30
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
32
|
spec.require_paths = ['lib']
|
32
33
|
|
33
|
-
spec.add_dependency 'red-arrow', '
|
34
|
+
spec.add_dependency 'red-arrow', '~> 10.0.0'
|
34
35
|
|
35
36
|
# Development dependency has gone to the Gemfile (rubygems/bundler#7237)
|
36
37
|
|