red_amber 0.4.2 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +75 -0
- data/.devcontainer/devcontainer.json +38 -0
- data/.devcontainer/onCreateCommand.sh +22 -0
- data/.rubocop.yml +11 -5
- data/CHANGELOG.md +141 -17
- data/Gemfile +5 -6
- data/README.ja.md +271 -0
- data/README.md +52 -31
- data/Rakefile +55 -0
- data/benchmark/group.yml +12 -5
- data/doc/Dev_Containers.ja.md +290 -0
- data/doc/Dev_Containers.md +292 -0
- data/doc/qmd/examples_of_red_amber.qmd +4596 -0
- data/doc/qmd/red-amber.qmd +90 -0
- data/docker/Dockerfile +2 -2
- data/docker/Gemfile +8 -3
- data/docker/docker-compose.yml +1 -1
- data/docker/readme.md +5 -5
- data/lib/red_amber/data_frame.rb +78 -4
- data/lib/red_amber/data_frame_combinable.rb +147 -119
- data/lib/red_amber/data_frame_displayable.rb +7 -6
- data/lib/red_amber/data_frame_loadsave.rb +1 -1
- data/lib/red_amber/data_frame_selectable.rb +51 -2
- data/lib/red_amber/data_frame_variable_operation.rb +6 -6
- data/lib/red_amber/group.rb +476 -127
- data/lib/red_amber/helper.rb +26 -0
- data/lib/red_amber/subframes.rb +18 -11
- data/lib/red_amber/vector.rb +45 -25
- data/lib/red_amber/vector_aggregation.rb +26 -0
- data/lib/red_amber/vector_selectable.rb +124 -40
- data/lib/red_amber/vector_string_function.rb +279 -0
- data/lib/red_amber/vector_unary_element_wise.rb +4 -0
- data/lib/red_amber/vector_updatable.rb +28 -0
- data/lib/red_amber/version.rb +1 -1
- data/lib/red_amber.rb +2 -1
- data/red_amber.gemspec +3 -3
- metadata +19 -14
- data/docker/Gemfile.lock +0 -80
- data/docker/example +0 -74
- data/docker/notebook/examples_of_red_amber.ipynb +0 -8562
- data/docker/notebook/red-amber.ipynb +0 -188
data/lib/red_amber/helper.rb
CHANGED
@@ -78,6 +78,32 @@ module RedAmber
|
|
78
78
|
Array(range)
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
# Create sink node and execute plan
|
83
|
+
#
|
84
|
+
# @param plan [Arrow::ExecutePlan]
|
85
|
+
# Execute plan of Acero.
|
86
|
+
# @param node [Arrow::ExecuteNode]
|
87
|
+
# Execute node of Acero.
|
88
|
+
# @param output_schema [Arrow::Schema, nil]
|
89
|
+
# Schema of table to output. If it is nil, output_schema of
|
90
|
+
# sink node is used.
|
91
|
+
# @return [Arrow::Table]
|
92
|
+
# Result of plan.
|
93
|
+
# @since 0.5.0
|
94
|
+
#
|
95
|
+
def sink_and_start_plan(plan, node, output_schema: nil)
|
96
|
+
sink_node_options = Arrow::SinkNodeOptions.new
|
97
|
+
plan.build_sink_node(node, sink_node_options)
|
98
|
+
plan.validate
|
99
|
+
plan.start
|
100
|
+
plan.wait
|
101
|
+
output_schema = node.output_schema if output_schema.nil?
|
102
|
+
reader = sink_node_options.get_reader(output_schema)
|
103
|
+
table = reader.read_all
|
104
|
+
plan.stop
|
105
|
+
table
|
106
|
+
end
|
81
107
|
end
|
82
108
|
|
83
109
|
# rubocop:disable Layout/LineLength
|
data/lib/red_amber/subframes.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RedAmber
|
4
|
-
# class SubFrames treats
|
4
|
+
# class SubFrames treats subsets of a DataFrame
|
5
5
|
# [Experimental feature] Class SubFrames may be removed or be changed in the future.
|
6
6
|
class SubFrames
|
7
7
|
include Enumerable # may change to use Forwardable.
|
@@ -20,6 +20,7 @@ module RedAmber
|
|
20
20
|
@sizes = []
|
21
21
|
end
|
22
22
|
|
23
|
+
# Generic iterator method
|
23
24
|
def each
|
24
25
|
@selectors.each
|
25
26
|
end
|
@@ -27,14 +28,20 @@ module RedAmber
|
|
27
28
|
|
28
29
|
# Boolean selectors of sub-dataframes
|
29
30
|
class Filters < Selectors
|
31
|
+
# Return sizes of filter
|
32
|
+
# @return [Array<Integer>]
|
33
|
+
# sizes of each sub dataframes.
|
34
|
+
# Counts true for each filter.
|
30
35
|
def sizes
|
31
|
-
# count true
|
32
36
|
@sizes = @selectors.map { |s| s.to_a.count { _1 } } # rubocop:disable Performance/Size
|
33
37
|
end
|
34
38
|
end
|
35
39
|
|
36
40
|
# Index selectors of sub-dataframes
|
37
41
|
class Indices < Selectors
|
42
|
+
# Return sizes of selector indices.
|
43
|
+
# @return [Array<Integer>]
|
44
|
+
# sizes of each sub dataframes.
|
38
45
|
def sizes
|
39
46
|
@sizes = @selectors.map(&:size)
|
40
47
|
end
|
@@ -93,7 +100,7 @@ module RedAmber
|
|
93
100
|
# @since 0.4.0
|
94
101
|
#
|
95
102
|
def by_group(group)
|
96
|
-
SubFrames.
|
103
|
+
SubFrames.by_filters(group.dataframe, group.filters)
|
97
104
|
end
|
98
105
|
|
99
106
|
# Create a new SubFrames object from a DataFrame and an array of indices.
|
@@ -291,15 +298,15 @@ module RedAmber
|
|
291
298
|
selectors = yield(dataframe)
|
292
299
|
end
|
293
300
|
|
294
|
-
if dataframe.empty? || selectors.nil? || selectors.
|
301
|
+
if dataframe.empty? || selectors.nil? || selectors.size.zero? # rubocop:disable Style/ZeroLengthPredicate
|
295
302
|
@baseframe = DataFrame.new
|
296
303
|
@selectors = Selectors.new([])
|
297
304
|
else
|
298
305
|
@baseframe = dataframe
|
299
306
|
@selectors =
|
300
|
-
if selectors
|
307
|
+
if selectors.first.boolean?
|
301
308
|
Filters.new(selectors)
|
302
|
-
elsif selectors
|
309
|
+
elsif selectors.first.numeric?
|
303
310
|
Indices.new(selectors)
|
304
311
|
else
|
305
312
|
raise SubFramesArgumentError, "illegal type: #{selectors}"
|
@@ -427,7 +434,7 @@ module RedAmber
|
|
427
434
|
# @return [DataFrame]
|
428
435
|
# created DataFrame.
|
429
436
|
# @example Aggregate by key labels in arguments and values from block.
|
430
|
-
# subframes.aggregate(:y, :sum_x) { [y.
|
437
|
+
# subframes.aggregate(:y, :sum_x) { [y.one, x.sum] }
|
431
438
|
#
|
432
439
|
# # =>
|
433
440
|
# #<RedAmber::DataFrame : 3 x 2 Vectors, 0x0000000000003b24>
|
@@ -438,7 +445,7 @@ module RedAmber
|
|
438
445
|
# 2 C 6
|
439
446
|
#
|
440
447
|
# @example Aggregate by key labels in an Array and values from block.
|
441
|
-
# subframes.aggregate([:y, :sum_x]) { [y.
|
448
|
+
# subframes.aggregate([:y, :sum_x]) { [y.one, x.sum] }
|
442
449
|
#
|
443
450
|
# # =>
|
444
451
|
# #<RedAmber::DataFrame : 3 x 2 Vectors, 0x0000000000003b24>
|
@@ -450,7 +457,7 @@ module RedAmber
|
|
450
457
|
#
|
451
458
|
# @overload aggregate
|
452
459
|
#
|
453
|
-
# Aggregate SubFrames creating DataFrame with pairs of key and aggregated
|
460
|
+
# Aggregate SubFrames creating DataFrame with pairs of key and aggregated values
|
454
461
|
# in Hash from the block.
|
455
462
|
#
|
456
463
|
# @yieldparam dataframe [DataFrame]
|
@@ -463,7 +470,7 @@ module RedAmber
|
|
463
470
|
# created DataFrame.
|
464
471
|
# @example Aggregate by key and value pairs from block.
|
465
472
|
# subframes.aggregate do
|
466
|
-
# { y: y.
|
473
|
+
# { y: y.one, sum_x: x.sum }
|
467
474
|
# end
|
468
475
|
#
|
469
476
|
# # =>
|
@@ -705,7 +712,7 @@ module RedAmber
|
|
705
712
|
# @example
|
706
713
|
# subframes.assign(:sum_x, :frac_x) do
|
707
714
|
# group_sum = x.sum
|
708
|
-
# [[group_sum] * size, x /
|
715
|
+
# [[group_sum] * size, x / group_sum.to_f]
|
709
716
|
# end
|
710
717
|
#
|
711
718
|
# # =>
|
data/lib/red_amber/vector.rb
CHANGED
@@ -10,21 +10,54 @@ module RedAmber
|
|
10
10
|
include ArrowFunction
|
11
11
|
include VectorUpdatable
|
12
12
|
include VectorSelectable
|
13
|
+
include VectorStringFunction
|
13
14
|
|
14
15
|
using RefineArrayLike
|
15
16
|
|
16
|
-
#
|
17
|
+
# Entity of Vector.
|
17
18
|
#
|
18
|
-
# @
|
19
|
-
#
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
# @return [Arrow::Array]
|
20
|
+
#
|
21
|
+
attr_reader :data
|
22
|
+
alias_method :to_arrow_array, :data
|
23
|
+
|
24
|
+
# Associated key name when self is in a DataFrame.
|
25
|
+
#
|
26
|
+
# Default Vector is 'head-less' (key-less).
|
27
|
+
# @return [Symbol]
|
23
28
|
#
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
attr_accessor :key
|
30
|
+
|
31
|
+
class << self
|
32
|
+
# Create a Vector (calling `.new`).
|
33
|
+
#
|
34
|
+
# @param (see #initialize)
|
35
|
+
# @return (see #initialize)
|
36
|
+
# @example Create an empty Vector.
|
37
|
+
# Vector[]
|
38
|
+
# # =>
|
39
|
+
# #<RedAmber::Vector(:string, size=0):0x000000000000e2cc>
|
40
|
+
# []
|
41
|
+
#
|
42
|
+
# @since 0.5.0
|
43
|
+
#
|
44
|
+
def [](...)
|
45
|
+
new(...)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Quicker constructor of Vector.
|
49
|
+
#
|
50
|
+
# @param arrow_array [Arrow::Array]
|
51
|
+
# Arrow::Array object to have in the Vector.
|
52
|
+
# @return [Vector]
|
53
|
+
# created Vector.
|
54
|
+
# @note This method doesn't check argment type.
|
55
|
+
#
|
56
|
+
def create(arrow_array)
|
57
|
+
instance = allocate
|
58
|
+
instance.instance_variable_set(:@data, arrow_array)
|
59
|
+
instance
|
60
|
+
end
|
28
61
|
end
|
29
62
|
|
30
63
|
# Create a Vector.
|
@@ -51,20 +84,6 @@ module RedAmber
|
|
51
84
|
end
|
52
85
|
end
|
53
86
|
|
54
|
-
# Entity of Vector.
|
55
|
-
#
|
56
|
-
# @return [Arrow::Array]
|
57
|
-
#
|
58
|
-
attr_reader :data
|
59
|
-
alias_method :to_arrow_array, :data
|
60
|
-
|
61
|
-
# Associated key name when self is in a DataFrame.
|
62
|
-
#
|
63
|
-
# Default Vector is 'head-less' (key-less).
|
64
|
-
# @return [Symbol]
|
65
|
-
#
|
66
|
-
attr_accessor :key
|
67
|
-
|
68
87
|
# Return other as a Vector which is same data type as self.
|
69
88
|
#
|
70
89
|
# @param other [Vector, Array, Arrow::Array, Arrow::ChunkedArray]
|
@@ -161,7 +180,8 @@ module RedAmber
|
|
161
180
|
end
|
162
181
|
sio << ']'
|
163
182
|
|
164
|
-
|
183
|
+
chunked = chunked? ? ', chunked' : ''
|
184
|
+
format "#<#{self.class}(:#{type}, size=#{size}#{chunked}):0x%016x>\n%s\n",
|
165
185
|
object_id, sio.string
|
166
186
|
end
|
167
187
|
end
|
@@ -161,6 +161,22 @@ module RedAmber
|
|
161
161
|
#
|
162
162
|
define_unary_aggregation :min_max
|
163
163
|
|
164
|
+
# Compute the 1 most common values and their respective
|
165
|
+
# occurence counts.
|
166
|
+
#
|
167
|
+
# @note Self must be a numeric or a boolean Vector.
|
168
|
+
# @note ModeOptions are not supported in 0.5.0 .
|
169
|
+
# Only one mode value is returned.
|
170
|
+
# @api private
|
171
|
+
# @return [Hash{'mode'=>mode, 'count'=>count}]
|
172
|
+
# mode and count of self in an array.
|
173
|
+
# @since 0.5.0
|
174
|
+
#
|
175
|
+
def mode
|
176
|
+
datum = find(:mode).execute([data])
|
177
|
+
datum.value.to_a.first
|
178
|
+
end
|
179
|
+
|
164
180
|
# Compute product value of self.
|
165
181
|
#
|
166
182
|
# @note Self must be a numeric Vector.
|
@@ -241,6 +257,16 @@ module RedAmber
|
|
241
257
|
# - nearest: returns i or j, whichever is closer.
|
242
258
|
# - midpoint: returns (i + j) / 2.
|
243
259
|
|
260
|
+
# Get a non-nil element in self.
|
261
|
+
#
|
262
|
+
# @return [Object, nil]
|
263
|
+
# first non-nil value detected. If all elements are nil, return nil.
|
264
|
+
# @since 0.5.0
|
265
|
+
#
|
266
|
+
def one
|
267
|
+
each.find { !_1.nil? }
|
268
|
+
end
|
269
|
+
|
244
270
|
# Returns a quantile value.
|
245
271
|
# - 0.5 quantile (median) is returned by default.
|
246
272
|
# - Or return quantile for specified probability (prob).
|
@@ -153,10 +153,23 @@ module RedAmber
|
|
153
153
|
# @param element
|
154
154
|
# an element of self.
|
155
155
|
# @return [integer, nil]
|
156
|
-
#
|
156
|
+
# position of element. If it is not found, returns nil.
|
157
157
|
#
|
158
158
|
def index(element)
|
159
|
-
|
159
|
+
if element.nil?
|
160
|
+
datum = find(:is_null).execute([data])
|
161
|
+
value = Arrow::Scalar.resolve(true, :boolean)
|
162
|
+
else
|
163
|
+
datum = data
|
164
|
+
value = Arrow::Scalar.resolve(element, type)
|
165
|
+
end
|
166
|
+
datum = find(:index).execute([datum], value: value)
|
167
|
+
index = get_scalar(datum)
|
168
|
+
if index.negative?
|
169
|
+
nil
|
170
|
+
else
|
171
|
+
index
|
172
|
+
end
|
160
173
|
end
|
161
174
|
|
162
175
|
# Returns first element of self.
|
@@ -229,55 +242,118 @@ module RedAmber
|
|
229
242
|
take(sort_indices(order: order))
|
230
243
|
end
|
231
244
|
|
232
|
-
# Returns numerical rank of self.
|
245
|
+
# Returns 1-based numerical rank of self.
|
233
246
|
# - Nil values are considered greater than any value.
|
234
247
|
# - NaN values are considered greater than any value but smaller than nil values.
|
235
|
-
# -
|
236
|
-
#
|
237
|
-
#
|
238
|
-
#
|
248
|
+
# - Order of each element is considered as ascending by default. It is
|
249
|
+
# changable by the parameter `order = :descending`.
|
250
|
+
# - Tiebreakers are ranked in order of appearance by default or
|
251
|
+
# with `tie: :first` option.
|
252
|
+
# - Null values (nil and NaN) are placed at end by default.
|
253
|
+
# This behavior can be changed by the option `null_placement: :at_start`.
|
254
|
+
#
|
255
|
+
# @param order [:ascending, '+', :descending, '-']
|
256
|
+
# the order of the elements should be ranked in.
|
257
|
+
# - :ascending or '+' : rank is computed in ascending order.
|
258
|
+
# - :descending or '-' : rank is computed in descending order.
|
259
|
+
# @param tie [:first, :min, :max, :dense]
|
260
|
+
# configure how ties between equal values are handled.
|
261
|
+
# - first: Ranks are assigned in order of when ties appear in the input.
|
262
|
+
# - min: Ties get the smallest possible rank in the sorted order.
|
263
|
+
# - max: Ties get the largest possible rank in the sorted order.
|
264
|
+
# - dense: The ranks span a dense [1, M] interval where M is the number
|
265
|
+
# of distinct values in the input.
|
266
|
+
# @param null_placement [:at_end, :at_start]
|
267
|
+
# configure the position of nulls to be located.
|
268
|
+
# Nulls are considered as `NaN < nil`.
|
239
269
|
# @return [Vector]
|
240
|
-
#
|
270
|
+
# 1-based rank in uint64 of self (1..size in range) at maximum.
|
241
271
|
# @example Rank of float Vector
|
242
|
-
#
|
272
|
+
# float = Vector[1, 0, nil, Float::NAN, Float::INFINITY, -Float::INFINITY, 3, 2]
|
273
|
+
# float
|
243
274
|
#
|
244
275
|
# # =>
|
245
|
-
# #<RedAmber::Vector(:double, size=
|
246
|
-
# [0.
|
276
|
+
# #<RedAmber::Vector(:double, size=8):0x0000000000036858>
|
277
|
+
# [1.0, 0.0, nil, NaN, Infinity, -Infinity, 3.0, 2.0]
|
247
278
|
#
|
248
|
-
#
|
279
|
+
# float.rank
|
280
|
+
# # or float.rank(:ascending, tie: :first, null_placement: :at_end)
|
249
281
|
#
|
250
282
|
# # =>
|
251
|
-
# #<RedAmber::Vector(:uint64, size=
|
252
|
-
# [
|
283
|
+
# #<RedAmber::Vector(:uint64, size=8):0x000000000003af84>
|
284
|
+
# [3, 2, 8, 7, 6, 1, 5, 4]
|
253
285
|
#
|
254
286
|
# @example Rank of string Vector
|
255
|
-
#
|
287
|
+
# string = Vector["A", "A", nil, nil, "C", "B"]
|
288
|
+
# string
|
289
|
+
#
|
290
|
+
# # =>
|
291
|
+
# #<RedAmber::Vector(:string, size=6):0x000000000003d568>
|
292
|
+
# ["A", "A", nil, nil, "C", "B"]
|
293
|
+
#
|
294
|
+
# string.rank
|
295
|
+
#
|
296
|
+
# # =>
|
297
|
+
# #<RedAmber::Vector(:uint64, size=6):0x0000000000049bc4>
|
298
|
+
# [1, 2, 5, 6, 4, 3]
|
299
|
+
#
|
300
|
+
# @example Rank with order = :descending
|
301
|
+
# float.rank(:descending) # or float.rank('-')
|
302
|
+
#
|
303
|
+
# # =>
|
304
|
+
# #<RedAmber::Vector(:uint64, size=8):0x000000000006ef00>
|
305
|
+
# [4, 5, 8, 7, 1, 6, 2, 3]
|
306
|
+
#
|
307
|
+
# @example Rank with tie: :min
|
308
|
+
# string.rank(tie: :min)
|
309
|
+
#
|
310
|
+
# # =>
|
311
|
+
# #<RedAmber::Vector(:uint64, size=6):0x000000000007a1d4>
|
312
|
+
# [1, 1, 5, 5, 4, 3]
|
313
|
+
#
|
314
|
+
# @example Rank with tie: :max
|
315
|
+
# string.rank(tie: :max)
|
316
|
+
#
|
317
|
+
# # =>
|
318
|
+
# #<RedAmber::Vector(:uint64, size=6):0x000000000007cba0>
|
319
|
+
# [2, 2, 6, 6, 4, 3]
|
320
|
+
#
|
321
|
+
# @example Rank with tie: :dense
|
322
|
+
# string.rank(tie: :dense)
|
256
323
|
#
|
257
324
|
# # =>
|
258
|
-
# #<RedAmber::Vector(:
|
259
|
-
# [
|
325
|
+
# #<RedAmber::Vector(:uint64, size=6):0x0000000000080930>
|
326
|
+
# [1, 1, 4, 4, 3, 2]
|
260
327
|
#
|
261
|
-
#
|
328
|
+
# @example Rank with null_placement: :at_start
|
329
|
+
# float.rank(null_placement: :at_start)
|
262
330
|
#
|
263
331
|
# # =>
|
264
|
-
# #<RedAmber::Vector(:uint64, size=
|
265
|
-
# [
|
332
|
+
# #<RedAmber::Vector(:uint64, size=8):0x0000000000082104>
|
333
|
+
# [5, 4, 1, 2, 8, 3, 7, 6]
|
266
334
|
#
|
267
335
|
# @since 0.4.0
|
268
336
|
#
|
269
|
-
def rank
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
337
|
+
def rank(order = :ascending, tie: :first, null_placement: :at_end)
|
338
|
+
func = find(:rank)
|
339
|
+
options = func.default_options
|
340
|
+
order =
|
341
|
+
case order.to_sym
|
342
|
+
when :+, :ascending, :increasing
|
343
|
+
:ascending
|
344
|
+
when :-, :descending, :decreasing
|
345
|
+
:descending
|
274
346
|
else
|
275
|
-
|
347
|
+
raise VectorArgumentError, "illegal order option: #{order}"
|
276
348
|
end
|
277
|
-
|
349
|
+
options.sort_keys = [Arrow::SortKey.resolve('', order)]
|
350
|
+
options.tiebreaker = tie
|
351
|
+
options.null_placement = null_placement
|
352
|
+
Vector.create(func.execute([data], options).value)
|
278
353
|
end
|
279
354
|
|
280
355
|
# Pick up elements at random.
|
356
|
+
# @note This method requires 'arrow-numo-narray' gem.
|
281
357
|
#
|
282
358
|
# @overload sample()
|
283
359
|
# Return a randomly selected element.
|
@@ -298,12 +374,12 @@ module RedAmber
|
|
298
374
|
# "C"
|
299
375
|
#
|
300
376
|
# @overload sample(n)
|
301
|
-
#
|
377
|
+
# Select n elements at random.
|
302
378
|
#
|
303
379
|
# @param n [Integer]
|
304
|
-
# positive number of elements to
|
305
|
-
# If n is smaller or equal to size, elements are
|
306
|
-
# If n is greater than `size`, elements are
|
380
|
+
# positive number of elements to select.
|
381
|
+
# If n is smaller or equal to size, elements are selected by non-repeating.
|
382
|
+
# If n is greater than `size`, elements are selected repeatedly.
|
307
383
|
# @return [Vector]
|
308
384
|
# sampled elements.
|
309
385
|
# If n == 1 (in case of `sample(1)`), it returns a Vector of size == 1
|
@@ -315,7 +391,7 @@ module RedAmber
|
|
315
391
|
# #<RedAmber::Vector(:string, size=1):0x000000000001a3b0>
|
316
392
|
# ["H"]
|
317
393
|
#
|
318
|
-
# @example Sample same size of self: every element is
|
394
|
+
# @example Sample same size of self: every element is selected in random order
|
319
395
|
# v.sample(8)
|
320
396
|
#
|
321
397
|
# # =>
|
@@ -330,18 +406,18 @@ module RedAmber
|
|
330
406
|
# ["E", "E", "A", "D", "H", "C", "A", "F", "H"]
|
331
407
|
#
|
332
408
|
# @overload sample(prop)
|
333
|
-
#
|
409
|
+
# Select elements by proportion `prop` at random.
|
334
410
|
#
|
335
411
|
# @param prop [Float]
|
336
|
-
# positive proportion of elements to
|
337
|
-
# Absolute number of elements to
|
338
|
-
# If prop is smaller or equal to 1.0, elements are
|
339
|
-
# If prop is greater than 1.0, some elements are
|
412
|
+
# positive proportion of elements to select.
|
413
|
+
# Absolute number of elements to select:`prop*size` is rounded (by `half: :up`).
|
414
|
+
# If prop is smaller or equal to 1.0, elements are selected by non-repeating.
|
415
|
+
# If prop is greater than 1.0, some elements are selected repeatedly.
|
340
416
|
# @return [Vector]
|
341
417
|
# sampled elements.
|
342
|
-
# If
|
418
|
+
# If selected element is only one, it returns a Vector of size == 1
|
343
419
|
# not a scalar.
|
344
|
-
# @example Sample same size of self: every element is
|
420
|
+
# @example Sample same size of self: every element is selected in random order
|
345
421
|
# v.sample(1.0)
|
346
422
|
#
|
347
423
|
# # =>
|
@@ -355,6 +431,14 @@ module RedAmber
|
|
355
431
|
# #<RedAmber::Vector(:string, size=16):0x00000000000233e8>
|
356
432
|
# ["H", "B", "C", "B", "C", "A", "F", "A", "E", "C", "H", "F", "F", "A", ... ]
|
357
433
|
#
|
434
|
+
# @example prop less than 1.0
|
435
|
+
# v.sample(0.7)
|
436
|
+
#
|
437
|
+
# # =>
|
438
|
+
# # Take (8 * 0.7).truncate => 5 samples
|
439
|
+
# #<RedAmber::Vector(:string, size=5):0x000000000001afe0>
|
440
|
+
# ["C", "A", "E", "H", "D"]
|
441
|
+
#
|
358
442
|
# @since 0.4.0
|
359
443
|
#
|
360
444
|
def sample(n_or_prop = nil)
|
@@ -367,7 +451,7 @@ module RedAmber
|
|
367
451
|
in Integer
|
368
452
|
n_or_prop
|
369
453
|
in Float
|
370
|
-
(n_or_prop * size).
|
454
|
+
(n_or_prop * size).truncate
|
371
455
|
in nil
|
372
456
|
return to_a.sample
|
373
457
|
else
|