carray 3.0.2 → 3.0.4
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/CHANGELOG.md +568 -0
- data/README.md +6 -6
- data/carray.gemspec +1 -1
- data/ext/ca_axis_descriptor.h +27 -24
- data/ext/ca_axis_dispatch.c +220 -0
- data/ext/ca_axis_group.c +201 -123
- data/ext/ca_binop_dispatch.c +46 -52
- data/ext/ca_binop_dispatch.h +1 -1
- data/ext/ca_categorical_iterator.c +249 -183
- data/ext/ca_compare.c +7 -12
- data/ext/ca_for_buffer.h +21 -68
- data/ext/ca_group_iter.c +38 -23
- data/ext/ca_kernel_iterator.c +1765 -2076
- data/ext/ca_kernel_iterator.h +584 -566
- data/ext/ca_monop_dispatch.c +86 -63
- data/ext/ca_monop_dispatch.h +5 -0
- data/ext/ca_obj_array.c +223 -56
- data/ext/ca_obj_bincmp.c +172 -138
- data/ext/ca_obj_binop.c +116 -230
- data/ext/ca_obj_bitarray.c +40 -26
- data/ext/ca_obj_bitfield.c +100 -68
- data/ext/ca_obj_block.c +19 -9
- data/ext/ca_obj_byte_swap.c +45 -46
- data/ext/ca_obj_const_string.c +269 -44
- data/ext/ca_obj_face.c +612 -89
- data/ext/ca_obj_face.h +111 -47
- data/ext/ca_obj_fake.c +36 -79
- data/ext/ca_obj_farray.c +7 -3
- data/ext/ca_obj_field.c +33 -8
- data/ext/ca_obj_fixlen_string.c +23 -24
- data/ext/ca_obj_grid.c +541 -210
- data/ext/ca_obj_meld.c +331 -111
- data/ext/ca_obj_moncmp.c +80 -65
- data/ext/ca_obj_monop.c +177 -149
- data/ext/ca_obj_object.c +664 -248
- data/ext/ca_obj_record.c +63 -23
- data/ext/ca_obj_reduce.c +18 -16
- data/ext/ca_obj_refer.c +140 -58
- data/ext/ca_obj_remap.c +85 -24
- data/ext/ca_obj_repeat.c +24 -9
- data/ext/ca_obj_roll.c +121 -16
- data/ext/ca_obj_select.c +61 -58
- data/ext/ca_obj_select_axis.c +73 -107
- data/ext/ca_obj_shift.c +32 -102
- data/ext/ca_obj_stack.c +372 -122
- data/ext/ca_obj_stride.c +348 -140
- data/ext/ca_obj_string.c +88 -22
- data/ext/ca_obj_tile.c +38 -21
- data/ext/ca_obj_time.c +45 -31
- data/ext/ca_obj_timedelta.c +43 -29
- data/ext/ca_obj_transpose.c +17 -6
- data/ext/ca_obj_triop.c +125 -141
- data/ext/ca_obj_window.c +330 -44
- data/ext/ca_op_ipower.c +24 -11
- data/ext/ca_op_powi.h +57 -30
- data/ext/ca_pow5_table.h +656 -0
- data/ext/ca_sort_kernels.h +70 -0
- data/ext/ca_sweep_engine.c +104 -81
- data/ext/ca_sweep_engine.h +7 -20
- data/ext/ca_triop_dispatch.c +4 -1
- data/ext/ca_triop_dispatch.h +5 -2
- data/ext/caframe_csv_reader.c +542 -0
- data/ext/carray.h +241 -92
- data/ext/carray_access.c +608 -276
- data/ext/carray_address_basis.c +494 -97
- data/ext/carray_attribute.c +129 -4
- data/ext/carray_bincount.c +39 -7
- data/ext/carray_broadcast.c +56 -19
- data/ext/carray_build_flags.h +1 -1
- data/ext/carray_call_cfunc.c +108 -28
- data/ext/carray_cast.c +1576 -223
- data/ext/carray_cast_func.rb +77 -24
- data/ext/carray_class.c +4 -3
- data/ext/carray_conversion.c +208 -75
- data/ext/carray_copy.c +82 -24
- data/ext/carray_core.c +646 -162
- data/ext/carray_count.c +171 -88
- data/ext/carray_element.c +94 -60
- data/ext/carray_factorize.c +670 -324
- data/ext/carray_generate.c +260 -83
- data/ext/carray_histogram.c +209 -106
- data/ext/carray_hold.c +14 -16
- data/ext/carray_index_classifier.c +422 -243
- data/ext/carray_internal.h +692 -3
- data/ext/carray_kernels_bincmp.c +7 -0
- data/ext/carray_kernels_binop.c +487 -120
- data/ext/carray_kernels_init.c +653 -50
- data/ext/carray_kernels_moncmp.c +15 -8
- data/ext/carray_kernels_monop.c +99 -43
- data/ext/carray_kernels_reduce_aggregate.c +3925 -6112
- data/ext/carray_kernels_reduce_boolean.c +112 -36
- data/ext/carray_kernels_reduce_cumulative.c +2127 -6903
- data/ext/carray_kernels_reduce_extreme.c +3032 -2892
- data/ext/carray_kernels_reduce_variance.c +439 -500
- data/ext/carray_kernels_scan.c +1097 -488
- data/ext/carray_kernels_search.c +3787 -2176
- data/ext/carray_kernels_sort.c +1200 -920
- data/ext/carray_kernels_triop.c +479 -7
- data/ext/carray_key_windows.c +216 -0
- data/ext/carray_lazy.c +967 -153
- data/ext/carray_loop.c +81 -65
- data/ext/carray_mask.c +910 -324
- data/ext/carray_math_kernel.h +1 -0
- data/ext/carray_median_percentile.c +299 -100
- data/ext/carray_memory_view.c +872 -758
- data/ext/carray_operator.c +1171 -364
- data/ext/carray_order.c +505 -133
- data/ext/carray_partition.c +112 -65
- data/ext/carray_random.c +327 -239
- data/ext/carray_round.c +273 -0
- data/ext/carray_scatter.c +346 -78
- data/ext/carray_segment.c +257 -0
- data/ext/carray_slab.c +249 -86
- data/ext/carray_sort.c +224 -227
- data/ext/carray_sort_kernel.c +8 -1
- data/ext/carray_struct.c +118 -39
- data/ext/carray_test.c +193 -69
- data/ext/carray_time_text.c +1182 -0
- data/ext/carray_undef.c +4 -0
- data/ext/carray_utils.c +579 -113
- data/ext/extconf.rb +27 -2
- data/ext/mk_call_cfunc.rb +19 -4
- data/ext/mk_pow5_table.rb +35 -0
- data/ext/mkkernel.rb +1202 -1014
- data/ext/ruby_carray.c +17 -5
- data/ext/version.h +4 -4
- data/ext/version.rb +4 -2
- data/lib/carray/attribute.rb +160 -17
- data/lib/carray/autoload_carray.rb +23 -27
- data/lib/carray/autoload_method_extension.rb +20 -5
- data/lib/carray/axis_group.rb +360 -63
- data/lib/carray/basics.rb +162 -28
- data/lib/carray/bincount_nd.rb +18 -2
- data/lib/carray/block_iterator.rb +231 -58
- data/lib/carray/boolean_reduce.rb +34 -42
- data/lib/carray/categorical.rb +242 -52
- data/lib/carray/categorical_iterator.rb +437 -827
- data/lib/carray/complex.rb +41 -34
- data/lib/carray/conditional.rb +150 -14
- data/lib/carray/const_string.rb +59 -4
- data/lib/carray/construct.rb +15 -11
- data/lib/carray/data_type_extension.rb +1 -0
- data/lib/carray/distance_limit.rb +77 -0
- data/lib/carray/fixlen_string.rb +7 -1
- data/lib/carray/frame/column_verbs.rb +70 -0
- data/lib/carray/frame/concat.rb +157 -6
- data/lib/carray/frame/convert.rb +82 -7
- data/lib/carray/frame/csv_parser.rb +688 -87
- data/lib/carray/frame/describe.rb +80 -0
- data/lib/carray/frame/frame.rb +369 -45
- data/lib/carray/frame/group.rb +631 -90
- data/lib/carray/frame/io.rb +506 -79
- data/lib/carray/frame/join.rb +411 -62
- data/lib/carray/frame/records.rb +116 -19
- data/lib/carray/frame/reshape.rb +455 -0
- data/lib/carray/frame/sort.rb +30 -18
- data/lib/carray/frame/verbs.rb +868 -61
- data/lib/carray/frame/windows.rb +117 -0
- data/lib/carray/frame.rb +4 -0
- data/lib/carray/fuse_source.rb +118 -2
- data/lib/carray/fusion.rb +257 -42
- data/lib/carray/histogram.rb +6 -1
- data/lib/carray/inspect.rb +54 -13
- data/lib/carray/iterator.rb +99 -9
- data/lib/carray/key_windows.rb +620 -0
- data/lib/carray/lazy.rb +216 -193
- data/lib/carray/mask_gap_fill.rb +112 -92
- data/lib/carray/math.rb +32 -19
- data/lib/carray/meld_reduce.rb +52 -21
- data/lib/carray/methods/align_addr.rb +8 -4
- data/lib/carray/methods/bin.rb +26 -18
- data/lib/carray/methods/bincount.rb +18 -2
- data/lib/carray/methods/bit_string.rb +15 -4
- data/lib/carray/methods/choose.rb +16 -3
- data/lib/carray/methods/composition.rb +18 -10
- data/lib/carray/methods/factorize.rb +2 -2
- data/lib/carray/methods/gather_nd.rb +25 -5
- data/lib/carray/methods/insert_block.rb +9 -14
- data/lib/carray/methods/is_between.rb +59 -0
- data/lib/carray/methods/is_in.rb +140 -10
- data/lib/carray/methods/join.rb +2 -7
- data/lib/carray/methods/lag.rb +49 -0
- data/lib/carray/methods/locate_addr.rb +182 -45
- data/lib/carray/methods/mode.rb +18 -1
- data/lib/carray/methods/nunique.rb +11 -6
- data/lib/carray/methods/repeat.rb +1 -20
- data/lib/carray/methods/resize.rb +21 -23
- data/lib/carray/methods/snap.rb +34 -12
- data/lib/carray/methods/unique.rb +11 -2
- data/lib/carray/methods/value_counts.rb +4 -11
- data/lib/carray/record_order.rb +208 -0
- data/lib/carray/rng.rb +3 -0
- data/lib/carray/runtime.rb +65 -17
- data/lib/carray/segment_iterator.rb +1221 -0
- data/lib/carray/serialize.rb +214 -30
- data/lib/carray/slab_iterator.rb +101 -27
- data/lib/carray/stack.rb +10 -4
- data/lib/carray/string.rb +105 -5
- data/lib/carray/string_operation_extension.rb +12 -4
- data/lib/carray/struct.rb +137 -58
- data/lib/carray/struct_builder.rb +124 -17
- data/lib/carray/time.rb +1222 -186
- data/lib/carray/window_iterator.rb +242 -81
- data/lib/carray.rb +9 -2
- data/yard-stubs/ca_obj_array.rb +4 -4
- data/yard-stubs/ca_obj_bitarray.rb +7 -0
- data/yard-stubs/ca_obj_bitfield.rb +23 -12
- data/yard-stubs/ca_obj_fake.rb +1 -1
- data/yard-stubs/ca_obj_field.rb +5 -1
- data/yard-stubs/ca_obj_grid.rb +21 -10
- data/yard-stubs/ca_obj_refer.rb +5 -4
- data/yard-stubs/ca_obj_roll.rb +2 -3
- data/yard-stubs/ca_obj_shift.rb +5 -1
- data/yard-stubs/ca_obj_stride.rb +10 -7
- data/yard-stubs/ca_obj_tile.rb +1 -1
- data/yard-stubs/ca_obj_transpose.rb +1 -1
- data/yard-stubs/ca_obj_window.rb +9 -5
- data/yard-stubs/carray_access.rb +11 -5
- data/yard-stubs/carray_attribute.rb +0 -5
- data/yard-stubs/carray_broadcast.rb +1 -1
- data/yard-stubs/carray_cast.rb +88 -43
- data/yard-stubs/carray_conversion.rb +15 -2
- data/yard-stubs/carray_copy.rb +12 -5
- data/yard-stubs/carray_core.rb +3 -3
- data/yard-stubs/carray_count.rb +9 -0
- data/yard-stubs/carray_element.rb +10 -4
- data/yard-stubs/carray_generate.rb +21 -1
- data/yard-stubs/carray_lazy.rb +5 -1
- data/yard-stubs/carray_loop.rb +4 -1
- data/yard-stubs/carray_mask.rb +60 -12
- data/yard-stubs/carray_math.rb +52 -14
- data/yard-stubs/carray_median_percentile.rb +15 -8
- data/yard-stubs/carray_memory_view.rb +40 -23
- data/yard-stubs/carray_order.rb +61 -29
- data/yard-stubs/carray_random.rb +13 -4
- data/yard-stubs/carray_scatter.rb +21 -9
- data/yard-stubs/carray_segment.rb +72 -0
- data/yard-stubs/carray_slab.rb +10 -2
- data/yard-stubs/carray_sort.rb +49 -8
- data/yard-stubs/carray_test.rb +15 -3
- data/yard-stubs/carray_utils.rb +0 -26
- metadata +19 -5
- data/ext/ca_for_each_element.h +0 -239
- data/ext/carray_kernels_map.c +0 -3467
- data/lib/carray/arrow_tensor.rb +0 -401
- data/lib/carray/table.rb +0 -108
data/lib/carray/histogram.rb
CHANGED
|
@@ -321,6 +321,7 @@ class CArray
|
|
|
321
321
|
|
|
322
322
|
if weights
|
|
323
323
|
raise ArgumentError, "weights given but accumulator is unweighted" unless @weighted
|
|
324
|
+
# coerce: the accumulator's type, declared by weights_data_type:
|
|
324
325
|
weights = CArray.wrap_readonly(weights, @counts_data_type)
|
|
325
326
|
expected_w_shape = chunk.shape.dup
|
|
326
327
|
expected_w_shape.delete_at(channel_ax)
|
|
@@ -447,7 +448,7 @@ class CArray
|
|
|
447
448
|
# @param weights [CArray, nil] optional per-sample weights.
|
|
448
449
|
# @return [Histogram] 1-D accumulator (`m == 1`).
|
|
449
450
|
def histogram1d (edges:, axis: -1, include_max: false, weights: nil)
|
|
450
|
-
ax = normalize_axis(axis, "histogram1d")
|
|
451
|
+
ax = normalize_axis(axis.nil? ? -1 : axis, "histogram1d")
|
|
451
452
|
|
|
452
453
|
new_shape = shape + [1]
|
|
453
454
|
arr_with_channel = reshape(*new_shape)
|
|
@@ -491,6 +492,10 @@ class CArray
|
|
|
491
492
|
def histogram (edges:, axis: [-2, -1], include_max: false, weights: nil)
|
|
492
493
|
raise ArgumentError, "edges must be an Array of edges arrays" unless edges.is_a?(Array)
|
|
493
494
|
arr = self
|
|
495
|
+
axis = [-2, -1] if axis.nil?
|
|
496
|
+
unless axis.is_a?(Array) && axis.size == 2
|
|
497
|
+
raise ArgumentError, "histogram: axis: is a [sample, channel] pair (got #{axis.inspect})"
|
|
498
|
+
end
|
|
494
499
|
sample_ax = normalize_axis(axis[0], "histogram sample axis")
|
|
495
500
|
channel_ax = normalize_axis(axis[1], "histogram channel axis")
|
|
496
501
|
fiber_shape = arr.shape.dup
|
data/lib/carray/inspect.rb
CHANGED
|
@@ -17,13 +17,12 @@ class CArray::Inspector # :nodoc:
|
|
|
17
17
|
raise "can't inspect CArray of ndim == 0"
|
|
18
18
|
end
|
|
19
19
|
formatter = get_formatter()
|
|
20
|
-
|
|
21
|
-
type_name = get_type_name()
|
|
20
|
+
label = get_label()
|
|
22
21
|
shape = get_shape()
|
|
23
22
|
data_spec = get_data_spec(0, Array.new(@carray.ndim){0}, formatter, abbrev)
|
|
24
23
|
info_list = get_info_list()
|
|
25
24
|
output = ["<",
|
|
26
|
-
format("%s
|
|
25
|
+
format("%s(%s)", label, shape.join(",")),
|
|
27
26
|
": ",
|
|
28
27
|
info_list.join(" "),
|
|
29
28
|
"\n",
|
|
@@ -35,6 +34,39 @@ class CArray::Inspector # :nodoc:
|
|
|
35
34
|
|
|
36
35
|
private
|
|
37
36
|
|
|
37
|
+
# The name before the shape: the class and the storage type, or for a
|
|
38
|
+
# Face its own name (see .face_label).
|
|
39
|
+
def get_label
|
|
40
|
+
return CArray::Inspector.face_label(@carray) if @carray.face?
|
|
41
|
+
return format("%s.%s", get_class_name, get_type_name)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
public
|
|
45
|
+
|
|
46
|
+
# The name a Face goes by where a person reads it -- the head of inspect,
|
|
47
|
+
# a frame's column list. A Face's data_type is the surface the kernels
|
|
48
|
+
# dispatch on (fixlen for a time, so arithmetic on it raises), which says
|
|
49
|
+
# nothing to a reader, so it is named by its class: what a private
|
|
50
|
+
# inspect_label gives (CATime adds its tick), or the class, with the
|
|
51
|
+
# surface type only for a Face whose surface is numeric.
|
|
52
|
+
# The type of an array as a person reads it in a message or a table: a
|
|
53
|
+
# Face by its name (face_label), any other array by its data type name.
|
|
54
|
+
# Every message and listing that names a type goes through here, so a
|
|
55
|
+
# Face is never named by its storage (:fixlen for a time).
|
|
56
|
+
def self.type_label (ca)
|
|
57
|
+
ca.face? ? face_label(ca) : CArray.data_type_name(ca.data_type).to_s
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def self.face_label (ca)
|
|
61
|
+
return ca.send(:inspect_label) if ca.respond_to?(:inspect_label, true)
|
|
62
|
+
klass = ca.class
|
|
63
|
+
klass = klass.superclass while klass.name.nil?
|
|
64
|
+
return klass.name if [CA_FIXLEN, CA_OBJECT].include?(ca.data_type)
|
|
65
|
+
"#{klass.name}.#{CArray.data_type_name(ca.data_type)}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
38
70
|
def get_class_name
|
|
39
71
|
return @carray.class.to_s
|
|
40
72
|
end
|
|
@@ -110,15 +142,27 @@ class CArray::Inspector # :nodoc:
|
|
|
110
142
|
end
|
|
111
143
|
|
|
112
144
|
def get_formatter
|
|
113
|
-
# A Face
|
|
145
|
+
# A Face can write its cells itself through a private
|
|
146
|
+
# inspect_cell_formatter, a lambda taking the decoded cell.
|
|
147
|
+
if @carray.respond_to?(:inspect_cell_formatter, true)
|
|
148
|
+
return @carray.send(:inspect_cell_formatter)
|
|
149
|
+
end
|
|
150
|
+
# A Face that defines storage_to_element decodes each cell into a surface
|
|
114
151
|
# value (CATime::Element, a String, a category label, ...) that has nothing
|
|
115
152
|
# to do with the storage data_type, so the formatter must follow the decoded
|
|
116
153
|
# value, not the storage. Faces without the hook (CAString) hand back the
|
|
117
154
|
# stored value itself and fall through to the storage formatters below.
|
|
118
|
-
if @carray.face? and @carray.respond_to?(:
|
|
155
|
+
if @carray.face? and @carray.respond_to?(:storage_to_element)
|
|
119
156
|
return lambda { |x| x.inspect }
|
|
120
157
|
end
|
|
121
|
-
|
|
158
|
+
data_type = @carray.data_type
|
|
159
|
+
# The same Faces behind a gated (fixlen) surface hand back the value of
|
|
160
|
+
# their storage, so they take the storage's formatter.
|
|
161
|
+
if @carray.face? and data_type == CA_FIXLEN and not @carray.data_class
|
|
162
|
+
storage = @carray.parent.data_type
|
|
163
|
+
data_type = storage unless storage == CA_FIXLEN
|
|
164
|
+
end
|
|
165
|
+
case data_type
|
|
122
166
|
when CA_BOOLEAN
|
|
123
167
|
# Boolean cells fetch as true/false; show compact 1/0 (masked = _).
|
|
124
168
|
# The type name in the inspect header distinguishes this from an int array.
|
|
@@ -134,11 +178,8 @@ class CArray::Inspector # :nodoc:
|
|
|
134
178
|
x.real.inspect, (x.imag >= 0) ? "+" : "-", x.imag.abs.inspect) }
|
|
135
179
|
when CA_FIXLEN
|
|
136
180
|
if @carray.data_class
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
else
|
|
140
|
-
lambda{|x| "%s" % (x.encode.chomp[0, 5]+"...").dump }
|
|
141
|
-
end
|
|
181
|
+
# A record shows its members, as the element's own inspect does.
|
|
182
|
+
lambda{|x| x.inspect }
|
|
142
183
|
else
|
|
143
184
|
if @carray.bytes <= 6
|
|
144
185
|
lambda{|x| "%s" % x.dump }
|
|
@@ -259,10 +300,10 @@ class CArray
|
|
|
259
300
|
case data_type
|
|
260
301
|
when CA_FIXLEN
|
|
261
302
|
output << sprintf("CArray.%s(%s, :bytes=>%i)",
|
|
262
|
-
data_type_name,
|
|
303
|
+
data_type_name, shape.inspect[1..-2], bytes)
|
|
263
304
|
else
|
|
264
305
|
output << sprintf("CArray.%s(%s)",
|
|
265
|
-
data_type_name,
|
|
306
|
+
data_type_name, shape.inspect[1..-2])
|
|
266
307
|
end
|
|
267
308
|
return output
|
|
268
309
|
end
|
data/lib/carray/iterator.rb
CHANGED
|
@@ -29,6 +29,55 @@ class CAIterator
|
|
|
29
29
|
attr_reader :ndim, :shape
|
|
30
30
|
alias dim shape
|
|
31
31
|
|
|
32
|
+
# The keywords a member passes on to a core reduction over its own axes.
|
|
33
|
+
# The member sets `axis:`, so one from the caller is refused; the rest go
|
|
34
|
+
# to the core, which checks them.
|
|
35
|
+
# Whether a fill method carries values backward: :forward / :ffill carry
|
|
36
|
+
# them forward, :backward / :bfill back. A member fills within its own
|
|
37
|
+
# pieces by holding the nearest present value; :linear, which needs a
|
|
38
|
+
# coordinate, is the core's alone.
|
|
39
|
+
def self.hold_backward? (method) # :nodoc:
|
|
40
|
+
case method
|
|
41
|
+
when :forward, :ffill then false
|
|
42
|
+
when :backward, :bfill then true
|
|
43
|
+
else
|
|
44
|
+
raise ArgumentError,
|
|
45
|
+
"strip_mask: method must be :forward, :ffill, :backward or :bfill " \
|
|
46
|
+
"within a piece (got #{method.inspect})"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# A one-cell (1, 1) array of the kind `value` holds, for asking the core
|
|
51
|
+
# what a reduction or scan of it answers in: its data type, cell width and,
|
|
52
|
+
# for a Face, its Face. A member that answers by a route of its own
|
|
53
|
+
# (a fused kernel, a fold by offset) takes its output type from here, so
|
|
54
|
+
# the route and the core cannot disagree. A Face is a view of the values
|
|
55
|
+
# themselves rather than a blank -- a Face cannot be allocated from its
|
|
56
|
+
# surface data type alone, and a zeroed record is not a valid cell for every
|
|
57
|
+
# one (a const string's record indexes a shared pool). A Face with no cell
|
|
58
|
+
# is asked with the blank cell its resize gives, so a reduction over no
|
|
59
|
+
# groups answers in the same kind as over some; this is nil only when the
|
|
60
|
+
# Face has no blank cell.
|
|
61
|
+
def self.core_probe (value) # :nodoc:
|
|
62
|
+
unless value.face?
|
|
63
|
+
return CArray.new(value.data_type, [1, 1], bytes: value.bytes)
|
|
64
|
+
end
|
|
65
|
+
flat = value.reshape(value.elements)
|
|
66
|
+
return flat[[0]].reshape(1, 1) if value.elements > 0
|
|
67
|
+
begin
|
|
68
|
+
flat.resize(1).reshape(1, 1)
|
|
69
|
+
rescue StandardError
|
|
70
|
+
nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.reduce_keywords (op, kw) # :nodoc:
|
|
75
|
+
if kw.key?(:axis)
|
|
76
|
+
raise ArgumentError, "#{op}: unknown keyword: :axis (the iterator sets the axes)"
|
|
77
|
+
end
|
|
78
|
+
kw
|
|
79
|
+
end
|
|
80
|
+
|
|
32
81
|
# The required reduction surface, modelled on the two reference members
|
|
33
82
|
# CASlabIterator and CACategoricalIterator (the surface they both provide).
|
|
34
83
|
# Declared abstract so a later member
|
|
@@ -117,6 +166,18 @@ class CAIterator
|
|
|
117
166
|
# Returns the five-number summary of each piece,
|
|
118
167
|
# `[min, Q1, median, Q3, max]`.
|
|
119
168
|
# @return [Array<CArray>] five arrays, one per position.
|
|
169
|
+
# @!method first
|
|
170
|
+
# Returns the first present value of each piece, in the piece's own
|
|
171
|
+
# order; a piece with no present value is UNDEF.
|
|
172
|
+
# @return [CArray] one value per piece, in the source's data type.
|
|
173
|
+
# @!method last
|
|
174
|
+
# Returns the last present value of each piece; a piece with no present
|
|
175
|
+
# value is UNDEF.
|
|
176
|
+
# @return [CArray] one value per piece, in the source's data type.
|
|
177
|
+
# @!method nunique
|
|
178
|
+
# Returns the number of distinct present values in each piece, as
|
|
179
|
+
# `CArray#nunique` counts them; a piece with none counts 0.
|
|
180
|
+
# @return [CArray] `:int64`, one count per piece.
|
|
120
181
|
# @!method count(value = nil)
|
|
121
182
|
# Returns a count per piece: with no argument the cells that are not
|
|
122
183
|
# masked, with `UNDEF` the masked cells, and with any other value the
|
|
@@ -144,19 +205,23 @@ class CAIterator
|
|
|
144
205
|
# @yieldparam piece [CArray] next piece.
|
|
145
206
|
# @yieldreturn [Object] updated accumulator.
|
|
146
207
|
# @return [Object] the final accumulator.
|
|
147
|
-
[
|
|
208
|
+
REQUIRED_SURFACE = [
|
|
148
209
|
:sum, :accumulate, :prod, :mean, :min, :max, # tier 1
|
|
149
210
|
:variance, :stddev, :all, :any,
|
|
150
211
|
:variancep, :stddevp, :minmax, # tier 2
|
|
151
212
|
:min_index, :max_index, :min_addr, :max_addr, # position
|
|
152
213
|
:wsum, :wmean, # weighted
|
|
153
214
|
:median, :percentile, :quantile, # tier 3
|
|
215
|
+
:first, :last, :nunique, # position / distinct
|
|
154
216
|
:count, :count_not_masked, :count_masked, :elements, # count family
|
|
155
217
|
:each, :reduce, # generic iterate
|
|
156
|
-
].
|
|
157
|
-
|
|
218
|
+
].freeze
|
|
219
|
+
|
|
220
|
+
REQUIRED_SURFACE.each do |name|
|
|
221
|
+
# define_method: a stub that names itself in its own message
|
|
222
|
+
define_method(name, &Ractor.make_shareable(proc do |*, **, &_blk|
|
|
158
223
|
raise NotImplementedError, "#{self.class} must implement ##{name}"
|
|
159
|
-
end
|
|
224
|
+
end))
|
|
160
225
|
end
|
|
161
226
|
|
|
162
227
|
# Recommended (should) surface -- template methods. These are well-defined
|
|
@@ -164,7 +229,8 @@ class CAIterator
|
|
|
164
229
|
# required: `map` is a per-piece element-wise transform scattered back to the
|
|
165
230
|
# source, `sort_addr` is a per-piece sort returning source flat addresses, and
|
|
166
231
|
# the segment scans (cumsum / cumprod / cummax / cummin / cumcount) write a
|
|
167
|
-
# per-cell running statistic of each piece
|
|
232
|
+
# per-cell running statistic of each piece, and `lag` the value some steps
|
|
233
|
+
# earlier in the same piece. A member implements each when it
|
|
168
234
|
# is well-defined and overrides it to raise with a reason when it is not. The
|
|
169
235
|
# scans belong here for the same reason as map: a running per-cell value is
|
|
170
236
|
# single-valued only when each cell belongs to exactly one piece, so the
|
|
@@ -209,11 +275,35 @@ class CAIterator
|
|
|
209
275
|
# masked within each piece.
|
|
210
276
|
# @return [CArray] shaped like the source.
|
|
211
277
|
# @raise [NotImplementedError] for a member whose pieces overlap.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
278
|
+
# @!method lag(n = 1)
|
|
279
|
+
# Returns a source-shaped array whose cell holds the value `n` steps
|
|
280
|
+
# earlier within the same piece, as `CArray#lag` does along an axis; a
|
|
281
|
+
# cell with no such value in its piece is UNDEF, so a lag never reaches
|
|
282
|
+
# across into another piece.
|
|
283
|
+
# @param n [Integer] steps back; a negative `n` looks ahead.
|
|
284
|
+
# @return [CArray] shaped like the source.
|
|
285
|
+
# @raise [NotImplementedError] for a member whose pieces overlap, where a
|
|
286
|
+
# cell has no single position within a piece.
|
|
287
|
+
# @!method strip_mask(method:)
|
|
288
|
+
# Returns a source-shaped array with each masked cell filled from its own
|
|
289
|
+
# piece, as `CArray#strip_mask(method:)` fills: `:forward` (`:ffill`)
|
|
290
|
+
# carries the last present value forward, `:backward` (`:bfill`) the next
|
|
291
|
+
# one back, never across into another piece.
|
|
292
|
+
# @param method [Symbol] `:forward`, `:ffill`, `:backward` or `:bfill`.
|
|
293
|
+
# @return [CArray] shaped like the source.
|
|
294
|
+
# @raise [NotImplementedError] for a member whose pieces overlap.
|
|
295
|
+
# @!method order(descending: false, method: :ordinal, kind: :quick)
|
|
296
|
+
# Returns a source-shaped int64 array of each cell's rank among the cells
|
|
297
|
+
# of its piece, as `CArray#order` ranks them (`0` the smallest).
|
|
298
|
+
# @return [CArray] shaped like the source.
|
|
299
|
+
# @raise [NotImplementedError] for a member whose pieces overlap, where a
|
|
300
|
+
# cell has no single rank.
|
|
301
|
+
[:map, :sort_addr, :order, :strip_mask,
|
|
302
|
+
:cumsum, :cumprod, :cummax, :cummin, :cumcount, :lag].each do |name|
|
|
303
|
+
# define_method: a stub that names itself in its own message
|
|
304
|
+
define_method(name, &Ractor.make_shareable(proc do |*, **, &_blk|
|
|
215
305
|
raise NotImplementedError, "#{self.class} does not provide ##{name} (optional)"
|
|
216
|
-
end
|
|
306
|
+
end))
|
|
217
307
|
end
|
|
218
308
|
|
|
219
309
|
end
|