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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d2edeb545754cf31d330c667913471c1a0035c97de72dabad7e7b2afb4fe272b
|
|
4
|
+
data.tar.gz: 8b34390fcabbb04c5e1f0926ae103052345196112ec3a6a16f244fb310df5583
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0f7430ff0556faf7b609673fb8cf9ef08279e226192995ea58a5dd203e5285733582c5cff0405fc753c39cad7056acd9194f55ba26ce9eb1d1a27cf1de8e37f0
|
|
7
|
+
data.tar.gz: 48d35829402ba2949e865712d8aa89dd9d4228f0ca4abf62719d3b2d32280541d1c6b7b01dba3e2a68927a89e258e0d6b474a20fc6177415154e1ab57f2b380d
|
data/CHANGELOG.md
CHANGED
|
@@ -34,6 +34,574 @@ and a newer one. The 1.x history, up to the 2.0.0 release, is in
|
|
|
34
34
|
neighbour ("as well", "the producer above") or leave unnamed the
|
|
35
35
|
method, class or keyword it is about. -->
|
|
36
36
|
|
|
37
|
+
## 3.0.4
|
|
38
|
+
|
|
39
|
+
- New: `CAFrame#verify(rules)` judges every row against named rules (each
|
|
40
|
+
a callable that returns a boolean CArray) and returns the verdicts as a
|
|
41
|
+
frame, one column per rule; a row whose rule read a masked value is
|
|
42
|
+
`UNDEF`, so `count(false)` counts the rows that break it.
|
|
43
|
+
|
|
44
|
+
- New: `CAFrame#join` takes `how: :semi` and `:anti` (the left rows that
|
|
45
|
+
have, or have no, match), several key columns (`on: ["station",
|
|
46
|
+
"date"]`), and the index as a key by the row axis name.
|
|
47
|
+
`CAFrame#join_asof` takes the index too, and `by:` columns that must
|
|
48
|
+
match exactly before the nearest key is taken.
|
|
49
|
+
|
|
50
|
+
- New: a `CAFrame` grouping has more verbs. The short form of `prod`,
|
|
51
|
+
`accumulate`, `median`, `variance`, `stddev`, `variancep`, `stddevp`,
|
|
52
|
+
`first`, `last`, `nunique`, `count`, `all` and `any`, beside `sum` /
|
|
53
|
+
`mean` / `min` / `max`; `filter` (keep the groups a block chooses);
|
|
54
|
+
`lag`, `order`, `cumsum` and the other running values, and
|
|
55
|
+
`fill(name, :ffill)` / `:bfill`, all kept on the frame's rows; and
|
|
56
|
+
`to_frame`. The reductions take column names (`grp.mean("temp")` is a
|
|
57
|
+
CArray) and `keep_rows: true`, which gives each row its own group's
|
|
58
|
+
result.
|
|
59
|
+
|
|
60
|
+
- New: `CAFrame#resample` takes `by:`, columns whose groups are binned
|
|
61
|
+
apart: `df.resample("time", "1 day", by: "station").max("temp")`.
|
|
62
|
+
|
|
63
|
+
- New: `CArray#windows(on:, before:, after:)` bounds each window by a
|
|
64
|
+
width of a key (a time, a duration or a number) instead of a count of
|
|
65
|
+
cells, with `by:`, `exclude:`, `interval:` and `at:` (windows placed at
|
|
66
|
+
given points, which may overlap). The key need not be sorted, and the
|
|
67
|
+
value may have several columns (shape `(N, ...)`). `CAFrame#windows(on:
|
|
68
|
+
"time", ...)` does the same for a frame's columns.
|
|
69
|
+
|
|
70
|
+
- New: `CArray#lag(n = 1, axis:)` is the value `n` steps earlier along an
|
|
71
|
+
axis, `UNDEF` where there is none, so `x - x.lag` starts with `UNDEF`.
|
|
72
|
+
|
|
73
|
+
- New: the slab, block, segment, categorical and axis-group iterators
|
|
74
|
+
have `lag`, `order` (each cell's rank within its piece) and
|
|
75
|
+
`strip_mask(method: :ffill / :bfill)`; each of them works within one
|
|
76
|
+
piece and never takes a value from another. Every iterator has `first`,
|
|
77
|
+
`last` and `nunique`.
|
|
78
|
+
|
|
79
|
+
- New: `CArray#is_between(lo, hi, exclude:)` (or a Range) is true where a
|
|
80
|
+
value lies between two bounds; `exclude: :lower`, `:upper` or `:both`
|
|
81
|
+
leaves bounds out, and `nil` or an open end leaves a side unbounded.
|
|
82
|
+
|
|
83
|
+
- New: `CArray#round(ndigits)` rounds each element to `ndigits` decimal
|
|
84
|
+
places (negative for tens, hundreds, ...), as `Float#round` and
|
|
85
|
+
`Integer#round` do.
|
|
86
|
+
|
|
87
|
+
- New: `CArray#to_frame(*names, axis: -1)` shows an array as a CAFrame
|
|
88
|
+
whose columns are views of it, one per position along `axis`.
|
|
89
|
+
|
|
90
|
+
- New: `CACategorical#contrast(base:, full:)` gives one int8 column per
|
|
91
|
+
category (1 in the cell's category, the base left out unless `full:
|
|
92
|
+
true`), and `CAFrame#contrast_columns(name, ...)` puts those columns in
|
|
93
|
+
the frame in place of the categorical.
|
|
94
|
+
|
|
95
|
+
- New: `CAFrame#is_duplicate(*names, except:)` is true for the rows that
|
|
96
|
+
repeat an earlier row in the named columns; `except: :last` or `:none`
|
|
97
|
+
chooses which occurrence stays unmarked.
|
|
98
|
+
|
|
99
|
+
- New: `CAFrame#append(name, col, before:, after:)` puts the column next
|
|
100
|
+
to another one.
|
|
101
|
+
|
|
102
|
+
- New: a `CAFrame` carries attributes of the frame as a whole (`attr`,
|
|
103
|
+
`set_attr`, `attrs`, ..., and `CAFrame.new(..., attrs:)`), separate from
|
|
104
|
+
each column's. A row selection or a change of columns keeps them; a
|
|
105
|
+
summary, a join or a reshape does not.
|
|
106
|
+
|
|
107
|
+
- New: `CAFrame#to_csv(attrs: [:units, ...])` writes one line per
|
|
108
|
+
attribute key below the names, and `CAFrame.from_csv(attrs: [...])`
|
|
109
|
+
reads them back as column attributes; in a reading block,
|
|
110
|
+
`r.header(:units)` does the same for a line anywhere in the header.
|
|
111
|
+
|
|
112
|
+
- New: `CAFrame.from_csv` `columns:` takes a Hash that selects and names
|
|
113
|
+
columns, and the names `c0`, `c1`, ... of a file without a header;
|
|
114
|
+
`cast` and `from_csv` `types:` take `:categorical`. `CAFrame.new` takes
|
|
115
|
+
`types:` and `on_error:`, as `from_records` does.
|
|
116
|
+
|
|
117
|
+
- New: `CArray#delete_attr(key)` removes an attribute and returns its
|
|
118
|
+
value.
|
|
119
|
+
|
|
120
|
+
- New: `CATime#end_of(unit:, origin:)` (the last tick of each time's
|
|
121
|
+
bucket), `days_in_month`, `quarter`, and the ISO 8601 week `iso_week`
|
|
122
|
+
with its year `iso_year`.
|
|
123
|
+
|
|
124
|
+
- New: a time or duration array takes a single value in `+` and `-`
|
|
125
|
+
(`t + "3 days"`, `t - t.min`, `t - Time.utc(2024, 1, 1)`), and a month
|
|
126
|
+
or year duration moves a time on a day or finer grid as `Date#>>` does
|
|
127
|
+
(`2024-01-31 + 1 month` is `2024-02-29`). A bare number is still
|
|
128
|
+
refused.
|
|
129
|
+
|
|
130
|
+
- New: a time array compares with a value off its grid (`days.eq(
|
|
131
|
+
"2024-01-03T05:00")`, `<`, `search_nearest`, `is_in`, ...) in the finer
|
|
132
|
+
unit the two share, where it raised `ArgumentError`. An assignment
|
|
133
|
+
still raises.
|
|
134
|
+
|
|
135
|
+
- New: `CATime#pmax` / `pmin` (and `maximum` / `minimum` / `fmax` /
|
|
136
|
+
`fmin`) give the later / earlier time cell by cell.
|
|
137
|
+
|
|
138
|
+
- New: CArray can be used in a Ractor other than the main one, `fuse`
|
|
139
|
+
included, and a frozen array is shared between Ractors without
|
|
140
|
+
copying. See `docs/topics/Ractor.md`.
|
|
141
|
+
|
|
142
|
+
- New: C extensions: `CA_FOR_EACH_WHOLE` and `CA_FOR_EACH_WHOLE_MASKED`
|
|
143
|
+
hand a kernel the whole array as one contiguous run.
|
|
144
|
+
|
|
145
|
+
- Change: `CArray#rank` is removed; use `#ndim`.
|
|
146
|
+
|
|
147
|
+
- Change: `CArray::TableMethods` (`column_names=`, `column`, `row`, `rows`
|
|
148
|
+
and `select` on a 2-D array) is removed; use `a.to_frame("x", "y")`,
|
|
149
|
+
then `df["x"]` for a column or `df.to_records[i]` for a row.
|
|
150
|
+
|
|
151
|
+
- Change: `CArray.load_arrow_tensor`, `CArray#save_arrow_tensor` and
|
|
152
|
+
`CArray::ArrowTensor`, the experimental Arrow tensor IPC reader and
|
|
153
|
+
writer, are removed.
|
|
154
|
+
|
|
155
|
+
- Change: methods whose names start and end with `__` that were public
|
|
156
|
+
internals are now private, renamed or removed. Call the public method
|
|
157
|
+
they served instead.
|
|
158
|
+
|
|
159
|
+
- Change: CAFrame takes column names as Strings only. A Symbol name
|
|
160
|
+
(`df.drop(:a)`, `join(on: :a)`, `CAFrame.new(axis_name: :row)`) raises
|
|
161
|
+
`TypeError`; write `"a"`. Record keys given to `from_records` may still
|
|
162
|
+
be Symbols, and `df[:x]` stays the predicate syntax.
|
|
163
|
+
|
|
164
|
+
- Change: a masked cell of an integer index array keeps its place:
|
|
165
|
+
`x[i]`, the grid forms and `CAFrame` row selection `df[i]` give a
|
|
166
|
+
result shaped like `i`, `UNDEF` where `i` is masked, where they dropped
|
|
167
|
+
those positions. To drop them as before, index by
|
|
168
|
+
`i[i.is_not_masked]`.
|
|
169
|
+
|
|
170
|
+
- Change: an index beside a CArray key is read as it is without one: a
|
|
171
|
+
range ending before its start reads backwards (`a[i, -1..1]`), and an
|
|
172
|
+
Integer key drops its axis (`a[i, 1]` has the shape of `i`; add `:_`
|
|
173
|
+
or use `1..1` to keep it).
|
|
174
|
+
|
|
175
|
+
- Change: an index with a Float that has a fraction (`a[1.5..3]`, a step
|
|
176
|
+
of `0.5`) raises `IndexError`; it was cut to an integer. Convert with
|
|
177
|
+
`to_i` or `round` first. A Float that holds an integer, such as a count
|
|
178
|
+
from `sum`, is still that position.
|
|
179
|
+
|
|
180
|
+
- Change: an index step says the direction, as in Ruby: a step pointing
|
|
181
|
+
away from the end reads nothing (`a[(0..4).step(-1)]` read `a[0]`).
|
|
182
|
+
|
|
183
|
+
- Change: a boolean selector of more than one axis must have the array's
|
|
184
|
+
shape; it picked cells by flat position. Flatten both sides to keep the
|
|
185
|
+
old reading.
|
|
186
|
+
|
|
187
|
+
- Change: storing an integer a cell cannot hold raises `RangeError`
|
|
188
|
+
(`CA_INT8([300])`, `a[0] = 300`, `fill`, `scatter_add!`, a record
|
|
189
|
+
member); it wrapped (`300` into int8 was `44`). Storing or reading a
|
|
190
|
+
NaN into an integer cell (`ints[] = floats`, `as_type`, `fake`) raises
|
|
191
|
+
`FloatDomainError`. To keep C's conversion, use `to_type`, which is
|
|
192
|
+
unchanged.
|
|
193
|
+
|
|
194
|
+
- Change: `CArray.time` reads an Integer as a count of ticks of `unit:`
|
|
195
|
+
(`CArray.time(CA_INT64([0, 10]), unit: :m)` is 00:00 and 00:10); it
|
|
196
|
+
read Unix seconds. To read Unix seconds onto another unit, write
|
|
197
|
+
`CArray.time(secs).to_unit(:m)`.
|
|
198
|
+
|
|
199
|
+
- Change: `CArray.time` without `unit:`, and `CAFrame#parse_to_time` with
|
|
200
|
+
a format or `:mixed`, read the values in the finest unit they show
|
|
201
|
+
(dates alone `:D`, fractions of a second `:ms` / `:us` / `:ns`); it was
|
|
202
|
+
always `:s`. Pass `unit: :s` to keep the old unit.
|
|
203
|
+
|
|
204
|
+
- Change: adding a duration that is coarser than a time's unit and not a
|
|
205
|
+
whole number of its ticks (`"1 day"` on a `"7 hours"` time) raises, and
|
|
206
|
+
so does `CArray#time(origin:)` between two ticks of `unit:`; both were
|
|
207
|
+
cut to the grid. Convert the time to a unit both share first.
|
|
208
|
+
|
|
209
|
+
- Change: `order(descending: true)` puts NaN last and keeps tied cells in
|
|
210
|
+
their original order (`[5, 3, 5, 1, 5]` gives `[0, 3, 1, 4, 2]`, was
|
|
211
|
+
`[2, 3, 1, 4, 0]`); with `method: :dense` the largest value is 0 and
|
|
212
|
+
the ranks have no gaps. Code that used `(n - 1) - order` for the
|
|
213
|
+
descending rank needs that formula written out. `nlargest` no longer
|
|
214
|
+
returns NaN or masked cells first, and `nsmallest` / `nlargest` and
|
|
215
|
+
their `_index` forms break ties by position.
|
|
216
|
+
|
|
217
|
+
- Change: a CAFrame column built from Ruby values is typed by them:
|
|
218
|
+
Integers `int64`, numbers `float64`, Strings a text column (`CAString`),
|
|
219
|
+
arrays of one shape an N-D column, anything else `:object`; it was
|
|
220
|
+
`:object`. This holds for `CAFrame.new("x" => [...])`, `df["x"] = [...]`,
|
|
221
|
+
a group's `table` block and a Proc in `aggregate`. Wrap the values in
|
|
222
|
+
`CA_OBJECT(...)` to keep an object column. A returned array is read
|
|
223
|
+
from the N-D column as `col[i, nil]`.
|
|
224
|
+
|
|
225
|
+
- Change: `CAFrame#melt` names each row's source in a text column
|
|
226
|
+
(`CAString`); it was an object column.
|
|
227
|
+
|
|
228
|
+
- Change: `CAFrame#group_by` on several keys gives a result with no
|
|
229
|
+
index: each key is a column, before the reduced columns. Read the keys
|
|
230
|
+
with `result["station"]` and so on, where the index held tuples.
|
|
231
|
+
|
|
232
|
+
- Change: `CAFrame#data_types`, `describe` and `p df` name a Face column
|
|
233
|
+
by its class (`CATime[D]`, `CAString`) where they gave its storage
|
|
234
|
+
`data_type` (`:fixlen` for most). Read the storage through the Face's
|
|
235
|
+
accessor (`ticks`, `codes`, ...).
|
|
236
|
+
|
|
237
|
+
- Change: a CAFrame verb that takes a list of columns refuses a name
|
|
238
|
+
given twice (`select("a", "a")`, `group_by("a", "a")`) with
|
|
239
|
+
`ArgumentError`. `df["a", "a"]` still gives the column twice.
|
|
240
|
+
|
|
241
|
+
- Change: a CAFrame group or window reduction over a column whose type
|
|
242
|
+
lacks it raises `CArray::DataTypeError`; it raised `ArgumentError`.
|
|
243
|
+
|
|
244
|
+
- Change: a `CAString` holds only Strings: storing `nil`, a number or an
|
|
245
|
+
Array into it raises (use `UNDEF` to mask a cell). A selection among
|
|
246
|
+
Strings (`then_else`, `choose`, `select`, `conditional`) and a
|
|
247
|
+
`CAString`'s String operators give a `CAString`, where they gave an
|
|
248
|
+
object array.
|
|
249
|
+
|
|
250
|
+
- Change: attributes follow conversions, views and copies but not
|
|
251
|
+
reductions: `categorize`, `cast`, `parse_to_time`, `dup`, Marshal and a
|
|
252
|
+
Face's views keep them, and `first` / `last` of a grouping no longer
|
|
253
|
+
carry them. A joined or concatenated array shows the keys every piece
|
|
254
|
+
shows with the same value. An attribute value is stored frozen; change
|
|
255
|
+
it by setting it again.
|
|
256
|
+
|
|
257
|
+
- Change: an error names the method you called, and the common refusals
|
|
258
|
+
open with it ("+: shape mismatch between operands ...", "fill: can not
|
|
259
|
+
modify read-only array"). The exception classes are unchanged; code
|
|
260
|
+
that matches a message needs the new text.
|
|
261
|
+
|
|
262
|
+
- Change: `clip` refuses `UNDEF` or a masked cell as a bound with
|
|
263
|
+
`ArgumentError`. To mask the cells out of range, pass `UNDEF` as the
|
|
264
|
+
fill (`clip(0, 10, UNDEF)`).
|
|
265
|
+
|
|
266
|
+
- Change: `is_in`, `intersection`, `difference` and `union` refuse a
|
|
267
|
+
Range; pass an Array (`(1..3).to_a`), or use `is_between` for an
|
|
268
|
+
interval.
|
|
269
|
+
|
|
270
|
+
- Change: `median`, `percentile` and `quantile` along the only axis of a
|
|
271
|
+
1-D array give a bare value, as `sum` does. `nunique(axis:)` naming
|
|
272
|
+
every axis gives an Integer; pass `keep_axis: true` to keep an array.
|
|
273
|
+
|
|
274
|
+
- Change: `valid_index?` and `valid_addr?` count a negative index from
|
|
275
|
+
the end, as `[]` does. `elem_fetch` on an empty array raises
|
|
276
|
+
`IndexError`; it returned `nil`.
|
|
277
|
+
|
|
278
|
+
- Change: `seq` / `seq!` on an integer array take a Float or Rational
|
|
279
|
+
start or step as `init_val + step*i` cut toward zero
|
|
280
|
+
(`int32.seq(0.5, 0.5)` is `[0, 1, 1, 2]`, was `[0, 0, 1, 1]`), and
|
|
281
|
+
raise `RangeError` for a start or Integer step the type cannot hold.
|
|
282
|
+
|
|
283
|
+
- Change: `random!` on an integer array raises for bounds the type
|
|
284
|
+
cannot hold or a Float bound, and clears the mask. `bin`, `bincount`,
|
|
285
|
+
`bincount_nd` and the histograms raise for a non-Integer count and for
|
|
286
|
+
edges that decrease.
|
|
287
|
+
|
|
288
|
+
- Change: MemoryView: `wrap_memory_view` refuses a boolean buffer (any
|
|
289
|
+
byte other than 0 or 1 cannot be told apart; use `from_memory_view`,
|
|
290
|
+
which reads it as true), and a wrap with a read-only `mask:` is
|
|
291
|
+
read-only. `CArray.memory_view_reject_reason` returns `nil` for an
|
|
292
|
+
object that is not a CArray.
|
|
293
|
+
|
|
294
|
+
- Change: C extensions: fifteen kernel iterator shorthand macros
|
|
295
|
+
(`CA_SLAB_REDUCE_F64`, `CA_SLAB_REDUCE_T_PLUS`,
|
|
296
|
+
`CA_L2_FOR_EACH_UNMASKED` and others) are removed; write the macro they
|
|
297
|
+
stood for (`CA_SLAB_REDUCE_T` with `double`, ...).
|
|
298
|
+
`ca_iter_state_next_slab_strided` is removed, and
|
|
299
|
+
`ca_iter_state_init_l2` takes `CA_SLAB_AXES` only.
|
|
300
|
+
|
|
301
|
+
## 3.0.3
|
|
302
|
+
|
|
303
|
+
- New: `CAFrame.from_csv` reads messy tables: `types: :infer` (numbers,
|
|
304
|
+
booleans, year-first dates and times), `types: { default: ... }`,
|
|
305
|
+
`missing:` tokens, `on_error:` (`:mask`, `:warn`, `:raise`), `columns:` to
|
|
306
|
+
read only some columns, and `header:` / `data:` / `column_names:` by line.
|
|
307
|
+
`CAFrame#cast` takes the same map; `parse_to_time(name, :infer)` finds a
|
|
308
|
+
column's date format; `describe` and `split_column` are new; `to_csv`
|
|
309
|
+
takes `encoding:` and `missing:`.
|
|
310
|
+
|
|
311
|
+
- New: `CAFrame` reshapes and resamples: `pivot` / `pivot_grid` / `melt`,
|
|
312
|
+
`stack_rows(by:)` / `unstack_rows`, `stack_columns` / `unstack_column`,
|
|
313
|
+
`CAFrame.stack` / `unstack` (frames as layers), and `resample(name, unit)`
|
|
314
|
+
for time bins. The stacked forms are views. `protect` makes a frame
|
|
315
|
+
read-only.
|
|
316
|
+
|
|
317
|
+
- New: `CAFrame` group reductions and `aggregate` reduce N-D columns along
|
|
318
|
+
the rows (a column `(N, L)` gives `(groups, L)`), take `min_count:` and
|
|
319
|
+
`fill_value:`, and pass a reduction its arguments
|
|
320
|
+
(`"p90" => ["temp", :percentile, 90.0]`).
|
|
321
|
+
|
|
322
|
+
- New: `value.segments(offsets:)` / `segments(lengths:)` iterate over
|
|
323
|
+
consecutive runs of cells, with `CArray.segment_offsets` /
|
|
324
|
+
`segment_index` to convert between lengths, boundaries and segment
|
|
325
|
+
numbers. The scans, `map`, `median` and `percentile` of
|
|
326
|
+
`group_by_category` take `axis:`, and a window's `median`, `percentile`
|
|
327
|
+
and `quantile` answer under the default `bounds: :skip`.
|
|
328
|
+
|
|
329
|
+
- New: `bitfield(range, type)` reads a field as a signed or wider integer;
|
|
330
|
+
`set_attrs(hash)`; `order(kind:)`; `tolerance: "10 minutes"` for time keys
|
|
331
|
+
in `locate_nearest_addr` and `CAFrame#join_asof`. A `CARecord` answers
|
|
332
|
+
`unique`, `value_counts`, `mode`, `is_in`, the set operations,
|
|
333
|
+
`categorize`, `count(v)` and `locate_addr`.
|
|
334
|
+
|
|
335
|
+
- New: for whoever registers a `CArray.expression_evaluator` (carray-jit):
|
|
336
|
+
mixed data types, integer powers, comparisons, `then_else`, `shift`, and
|
|
337
|
+
reductions, scans and sorts of an expression now reach the evaluator. An
|
|
338
|
+
evaluator that does not know a node declines, and CArray computes the
|
|
339
|
+
expression as before.
|
|
340
|
+
|
|
341
|
+
- New: for C extensions: `ca_iter_ensure`, `ca_sync_detach`,
|
|
342
|
+
`ca_attach_n` / `ca_allocate_n`, `ca_iter_state_init_l2_paired`,
|
|
343
|
+
`ca_stride_setup(NULL, ...)` and `ca_check_uninitialized` let an
|
|
344
|
+
extension clean up when its code raises.
|
|
345
|
+
|
|
346
|
+
- Change: `CAFrame` names its columns "columns": `variable_names` is now
|
|
347
|
+
`column_names`, `variables` is `columns` and `nvar` is `ncol`. The old
|
|
348
|
+
names are gone.
|
|
349
|
+
|
|
350
|
+
- Change: `sort_index`, `rank_index`, `partition_index`, `partition` and
|
|
351
|
+
`partition_copy` without `axis:` work on the whole array, as `sort` does;
|
|
352
|
+
they worked along axis 0. On an N-D array pass `axis: 0` to keep the old
|
|
353
|
+
result.
|
|
354
|
+
|
|
355
|
+
- Change: errors a caller can cause no longer raise `RuntimeError`: a bad
|
|
356
|
+
shape, step, axis, option or data type raises `ArgumentError`,
|
|
357
|
+
`TypeError`, `RangeError` or `CArray::DataTypeError`, and every index out
|
|
358
|
+
of range raises `IndexError` (`take_along_axis`, `axis2addr` and
|
|
359
|
+
`addr2index` raised others). `CArray::DataTypeError` is now a
|
|
360
|
+
`TypeError`. A write to a read-only array still raises `RuntimeError`.
|
|
361
|
+
Messages name the method you called and the value you gave. Update a
|
|
362
|
+
`rescue` that matched the old class or wording.
|
|
363
|
+
|
|
364
|
+
- Change: arguments that were truncated or ignored now raise: an axis,
|
|
365
|
+
`min_count:`, `kth` or `n` that is not an Integer; a misspelt keyword; a
|
|
366
|
+
keyword a method does not take (`min_count:` to `all` / `any` of an
|
|
367
|
+
iterator, as to the core); a Symbol column name in `cast` and `types:`;
|
|
368
|
+
`windows` given anything but Ranges (an exclusive range now leaves out
|
|
369
|
+
its end); `CA_INT32(0, 2)`; a fixlen array without `bytes:`. A negative
|
|
370
|
+
axis counts from the end everywhere. The indexer's method form
|
|
371
|
+
(`a[:eq, 0]`) calls public methods only.
|
|
372
|
+
|
|
373
|
+
- Change: a Hash passed as a positional argument is an argument, as in
|
|
374
|
+
Ruby 3, not keywords: `a.sum({axis: 0})` raises (write `a.sum(axis: 0)`
|
|
375
|
+
or `a.sum(**opts)`). An object array of Hashes can now be searched and
|
|
376
|
+
counted.
|
|
377
|
+
|
|
378
|
+
- Change: values that cannot be held raise instead of being bent: storing
|
|
379
|
+
`nil` into a numeric or boolean array, an Integer operand the array's type
|
|
380
|
+
cannot hold (`RangeError`; the comparisons answer by value instead), and a
|
|
381
|
+
String that is not a decimal number (`"010"` is now 10, and `to_type` gives
|
|
382
|
+
`UNDEF`). `CAFrame#cast` to an integer makes `2.5` `UNDEF` instead of 2.
|
|
383
|
+
Store `Float::NAN` or `UNDEF` for a missing value.
|
|
384
|
+
|
|
385
|
+
- Change: reductions with too few values: `variance` / `stddev` of fewer
|
|
386
|
+
than two values is `UNDEF` (pass `fill_value: 0.0` for the old answer),
|
|
387
|
+
and `minmax` of nothing is `[UNDEF, UNDEF]`. `fill_value:` is stored into
|
|
388
|
+
the result's type with or without `axis:`; `fill_value: UNDEF`,
|
|
389
|
+
`strip_mask(UNDEF)` and `unmask(UNDEF)` leave the cells masked.
|
|
390
|
+
|
|
391
|
+
- Change: arrays of mixed types meet in a type that holds both: signed with
|
|
392
|
+
unsigned integers (`uint8` with `int8` is `int16`, `uint64` with `int64` is
|
|
393
|
+
`:object`) and 32-bit or wider integers with `float32` (in `float64`) when
|
|
394
|
+
joined or matched. `CArray.result_type` lets a scalar take the arrays'
|
|
395
|
+
type, as an operator does (`result_type(float32_array, 0.1)` is
|
|
396
|
+
`:float32`). Arithmetic is unchanged.
|
|
397
|
+
|
|
398
|
+
- Change: integer and float edge cases no longer depend on the machine or
|
|
399
|
+
the argument order: a shift count means what it does to `Integer#<<`,
|
|
400
|
+
signed `rcp` / `rcp_mul` round down as `/` does, `to_type` to an integer
|
|
401
|
+
makes NaN `UNDEF`, `maximum` / `minimum` of two zeros are `0.0` / `-0.0`,
|
|
402
|
+
and `clip` raises when `min` exceeds `max` (a one-sided fill clamps the
|
|
403
|
+
other side).
|
|
404
|
+
|
|
405
|
+
- Change: `CAFrame#join` matches as SQL joins do: a key on 2 left and 3
|
|
406
|
+
right rows gives 6 rows, and a masked key matches nothing and stays as an
|
|
407
|
+
unmatched row. When the other frame's key is unique, `:left` gives the
|
|
408
|
+
same rows as before.
|
|
409
|
+
|
|
410
|
+
- Change: `CAFrame.from_csv`'s reading block takes the reader as its
|
|
411
|
+
parameter and its `body` verb is `data`
|
|
412
|
+
(`from_csv(path) { |r| r.skip 2; r.header; r.data }`). Text columns come
|
|
413
|
+
back as `CAString`. Contents that cannot be read raise
|
|
414
|
+
`CAFrame::UnreadableColumn` or `CAFrame::AmbiguousTimeFormat`, which are
|
|
415
|
+
not `ArgumentError`.
|
|
416
|
+
|
|
417
|
+
- Change: reading time from text is stricter: `parse_to_time` without a
|
|
418
|
+
format reads year-first text only (pass a format, or `:mixed` for the old
|
|
419
|
+
guess) in the finest unit the text shows; `CArray.time` and strptime
|
|
420
|
+
formats refuse trailing text and a time of day they cannot read; a date
|
|
421
|
+
the column's unit cannot hold raises `RangeError`. Before, these cells
|
|
422
|
+
were guessed, floored or masked.
|
|
423
|
+
|
|
424
|
+
- Change: `CAFrame#to_csv` writes a boolean as `1` / `0` and a float32 as
|
|
425
|
+
its shortest decimal, refuses a record column, and raises naming the row
|
|
426
|
+
and column of a cell it cannot encode. `extract` masks a cell its pattern
|
|
427
|
+
does not match, where it gave `""`.
|
|
428
|
+
|
|
429
|
+
- Change: `CAFrame`: a frozen frame refuses `[]=`, `set_index`, `cast` and
|
|
430
|
+
the other in-place verbs; `at` on a numeric index takes numbers only; the
|
|
431
|
+
index of a `group_by` result keeps the key's type (a `CATime` key gives a
|
|
432
|
+
`CATime` index); group `sum` / `mean` / `min` / `max` include every column
|
|
433
|
+
whose type has the reduction (times and strings among them).
|
|
434
|
+
|
|
435
|
+
- Change: `CAStruct` / `CARecord`: records are ordered only by the members
|
|
436
|
+
named in `CArray.struct(order_by:)`; without it sorting, `min` / `max` and
|
|
437
|
+
comparison raise. An element's `[]` takes a String or a position (a
|
|
438
|
+
Symbol raises), a member named like a method (`hash`, `size`) gets no
|
|
439
|
+
accessor, a nested member reads as a view (`dup` it for a copy), boolean
|
|
440
|
+
and 1-bit members read as `true` / `false`, and `UNDEF` cannot be stored
|
|
441
|
+
in a member. Records of another struct are refused.
|
|
442
|
+
|
|
443
|
+
- Change: a `CARecord` exported through MemoryView uses Ruby's own format
|
|
444
|
+
(`ruby/memory_view.h`) instead of PEP 3118 `T{...}`; the member names are
|
|
445
|
+
`CARecord#memory_view_field_names`. A union is no longer exported.
|
|
446
|
+
|
|
447
|
+
- Change: a time array compares with, searches for and stores a `String` or
|
|
448
|
+
`Date` as well as a `Time`, at the precision the value carries: a value
|
|
449
|
+
off the array's grid (09:00 against a day array) raises, where a `Time`
|
|
450
|
+
was floored. `union` of two units gives the finer unit. `inspect` shows
|
|
451
|
+
the tick and each cell as `to_s` does.
|
|
452
|
+
|
|
453
|
+
- Change: `==` on a Face (a time, string or categorical array) compares the
|
|
454
|
+
values it holds, and only with a Face of its own class: time arrays of
|
|
455
|
+
different units holding the same instants are `==`, and a `CAString` is
|
|
456
|
+
no longer `==` to an object array of the same strings (compare
|
|
457
|
+
`to_type(:object)` for that).
|
|
458
|
+
|
|
459
|
+
- Change: Faces (`CATime`, `CATimedelta`, `CACategorical`, string arrays):
|
|
460
|
+
`.lazy` returns the Face and computes eagerly; storing one into a
|
|
461
|
+
non-object plain array raises (convert with `to_type(:object)` or
|
|
462
|
+
`ticks`); `CArray.save`, `dump` and `Marshal.dump` refuse one, and a
|
|
463
|
+
`CAWrap` (save `.parent` or `.copy`); `CArray.stack([face])` returns the
|
|
464
|
+
Face, and mixing Faces raises.
|
|
465
|
+
|
|
466
|
+
- Change: for whoever writes a Face: the hooks are renamed
|
|
467
|
+
`storage_to_element` / `element_to_storage`, and a stored value goes
|
|
468
|
+
through `element_to_storage` once (it went through twice). A Face written
|
|
469
|
+
in Ruby on `CAObject` over a numeric storage refuses arithmetic, math and
|
|
470
|
+
reductions unless it passes `numeric: true`.
|
|
471
|
+
|
|
472
|
+
- Change: views: a view of a frozen array is read-only rather than frozen
|
|
473
|
+
(`RuntimeError`, `frozen?` false), so `sort`, selections and lazy
|
|
474
|
+
expressions work on a frozen array. `then_else` and `sort` on a lazy
|
|
475
|
+
expression return a read-only lazy view (call `copy` for a snapshot), and
|
|
476
|
+
`then_else` branches broadcast as operands do. `dup` of a `CAWrap` is a
|
|
477
|
+
plain `CArray`. Attributes survive `copy` and `to_type`.
|
|
478
|
+
|
|
479
|
+
- Change: a `bitarray` view has no mask and refuses a masked array (use
|
|
480
|
+
`value.bitarray`); `pack_bits` raises on masked cells (pack the mask with
|
|
481
|
+
`validity_bits`). `bitfield` refuses a complex array.
|
|
482
|
+
|
|
483
|
+
- Change: on an object array, `min`, `max`, `cummin`, `pmin` and the rest
|
|
484
|
+
compare with `<=>`, as `sort` does; a pair that cannot be ordered raises
|
|
485
|
+
`ArgumentError`. `median`, `percentile` and `quantile` answer in the
|
|
486
|
+
elements' own arithmetic (`CA_OBJECT([1, 2]).median` is `3/2`; convert
|
|
487
|
+
with `to_type(:float64)` for a Float). `&`, `|` and `^` with a boolean
|
|
488
|
+
array read its cells as `true` / `false`, eager and lazy.
|
|
489
|
+
|
|
490
|
+
- Change: smaller behaviour changes: `locate_nearest_addr` (and `join_asof`,
|
|
491
|
+
`snap_to`) with `direction:` matches beyond the reference's ends (limit it
|
|
492
|
+
with `tolerance:`); `map_slab` carries the mask of the block's result; a
|
|
493
|
+
masked cell of a one-axis boolean selector selects nothing; `shift`,
|
|
494
|
+
`roll`, `tile` and `window` on a zero-length axis return an empty view;
|
|
495
|
+
boolean sums in `axis_group` and categorical scans are uint64, as in the
|
|
496
|
+
core; `group_by_category` raises `TypeError` for a non-categorical.
|
|
497
|
+
|
|
498
|
+
- Change: an operand that exports MemoryView and defines `to_ca` (an Arrow
|
|
499
|
+
array, with a bridge) is taken through `to_ca`, so Arrow nulls arrive as
|
|
500
|
+
masked cells and time columns as `CATime`.
|
|
501
|
+
|
|
502
|
+
- Change: for C extensions: `CArray::VERSION_CODE` is
|
|
503
|
+
`major*10000 + minor*100 + teeny` (`30003`); the `CA_FOR_EACH_ELEMENT`
|
|
504
|
+
macros, `CA_WITH_BUFFER` and `CA_CHECK_BOUND` are removed (use
|
|
505
|
+
`ca_call_cslab_N_r`, `ca_call_cfunc_N_r` or `rb_ca_call_with_buffer`);
|
|
506
|
+
the `_INOUT` and `_PAIR` fiber macros raise on a shape mismatch; kernels
|
|
507
|
+
are built with `-fwrapv`. Rebuild the extension.
|
|
508
|
+
|
|
509
|
+
- Change: faster, with the same results: `from_csv` with `types:` (two to
|
|
510
|
+
five times), text to float (eight times), `CAConstString#to_string`,
|
|
511
|
+
reductions over gathered, `shift` and `window` views, a repeated
|
|
512
|
+
`CArray.fuse` block, and selecting from a lazy expression.
|
|
513
|
+
|
|
514
|
+
- Fix: wrong answers that came without an error. An in-place operation
|
|
515
|
+
reading an argument that shares its memory read cells it had already
|
|
516
|
+
written (`a[1..5].add!(a[0..4])` gave a running sum; `scatter_*!`,
|
|
517
|
+
`inherit_mask` and `mask=` too); `refer` to a wider type on a transposed
|
|
518
|
+
or stepped parent read neighbouring values; views of a stack or meld,
|
|
519
|
+
and a slice of a lazy expression, returned other cells; a Float operand
|
|
520
|
+
of an integer array was truncated (`count(1.5)` found `1`); `mask=` with
|
|
521
|
+
another shape copied cells by count; a masked index read cell 0 in
|
|
522
|
+
`gather_nd`; `stddev` of NaN data was 0.0.
|
|
523
|
+
|
|
524
|
+
- Fix: wrong answers that came without an error, time and strings: time
|
|
525
|
+
keys of different units matched or not depending on the side in `is_in`,
|
|
526
|
+
`join` and `align`; `locate_nearest_addr` picked a wrong row for a NaN,
|
|
527
|
+
an infinite or a nanosecond key; `unmask(time)`, `resize(fill_value:)`
|
|
528
|
+
and `insert_block` read a `Time` as a count; `CAConstString` comparisons
|
|
529
|
+
compared buffer positions; a `CAString` compared against a time,
|
|
530
|
+
categorical or const string compared their encodings.
|
|
531
|
+
|
|
532
|
+
- Fix: writes that were lost now reach the array: through a grid, selection
|
|
533
|
+
or `select_axis` over a reshaped transpose, through a stack or meld of
|
|
534
|
+
views, into a nested struct member, into the mask copy of a stack or meld,
|
|
535
|
+
and the masked cells of `c[] = c.flip(0)`.
|
|
536
|
+
|
|
537
|
+
- Fix: crashes and reads outside an array: a garbage collection during an
|
|
538
|
+
operation on a converted or computed array (`CAObject`, lazy, object
|
|
539
|
+
data); a slab kept after `each_slab`; a `CARecord` after `Marshal.load`;
|
|
540
|
+
shapes and indices whose arithmetic overflows; `refer(:object)` and
|
|
541
|
+
`bitfield` on object data; `scatter_*!` on complex; `MIN / -1` on Linux
|
|
542
|
+
x86; struct members outside the record; fixlen stores of another width;
|
|
543
|
+
reductions in several Ractors.
|
|
544
|
+
|
|
545
|
+
- Fix: an operation that raises part way (a block, a conversion, a
|
|
546
|
+
division by zero) leaves its arrays usable and frees its memory. Before,
|
|
547
|
+
an array could stay attached, and after 32 such errors every lazy
|
|
548
|
+
expression failed with "all 32 slots in use".
|
|
549
|
+
|
|
550
|
+
- Fix: iterator reductions answer as the same reduction on an array: every
|
|
551
|
+
one takes `min_count:` and `fill_value:` (`blocks(n).percentile(p,
|
|
552
|
+
min_count: k)` read them as a second percentile), a group's counts apply
|
|
553
|
+
`min_count:` to the right cells, a group's `wmean` no longer takes
|
|
554
|
+
`fill_value:` as a weight, a window of only NaN gives NaN, and object
|
|
555
|
+
weights in `segments` stay exact.
|
|
556
|
+
|
|
557
|
+
- Fix: `CAFrame` round trips through CSV and records: quotes, separators of
|
|
558
|
+
several characters or spaces, lines of spaces, a duplicated header name,
|
|
559
|
+
complex `Infinity` / `NaN`, months and years, hour 24, a one-column file
|
|
560
|
+
with a blank name; nested arrays, `Complex` and `Rational` in
|
|
561
|
+
`from_records`. `fill`, `to_table` and `filter(keep_masked:)` work with
|
|
562
|
+
N-D and categorical columns; `meld` and `concatenate` take empty frames;
|
|
563
|
+
`group_by` takes a categorical key and treats NaN in a composite key as
|
|
564
|
+
one value.
|
|
565
|
+
|
|
566
|
+
- Fix: Faces stay Faces: the reductions of `windows` and `blocks`,
|
|
567
|
+
`partition_copy`, `then_else`, `clip`, `mask_eq` and `meld` return the
|
|
568
|
+
Face, and a Face's own state survives `min(axis:)`, `cummax` and
|
|
569
|
+
`partition_copy`. `axis_group` and categorical reductions take boolean,
|
|
570
|
+
complex, object and Face values; a time array's `fill_value:` is a time
|
|
571
|
+
on every path. `CAFrame#fill(:linear)` interpolates any Face that defines
|
|
572
|
+
`linear_fetch`. A categorical refuses `clip` and `minmax` as it refuses
|
|
573
|
+
`min`.
|
|
574
|
+
|
|
575
|
+
- Fix: types kept through operations: complex arrays work with `unique`,
|
|
576
|
+
`is_in` and the rest of that family; `meld` reductions answer as on a
|
|
577
|
+
copy; fixlen strings of different widths match; `atan2`, `hypot` and
|
|
578
|
+
others keep float32 and integer types; a record member declared with
|
|
579
|
+
`endian:` reads, sorts, saves and loads correctly.
|
|
580
|
+
|
|
581
|
+
- Fix: NaN and masked cells are treated the same everywhere: NaN is last in
|
|
582
|
+
object sorts and `categorize`, loses `min` / `max`, and is found by
|
|
583
|
+
`CAFrame#at(Float::NAN)`; `min_index` never points at a masked cell or a
|
|
584
|
+
NaN; `min_count:` and `fill_value:` are honoured where they were ignored;
|
|
585
|
+
a lazy expression's mask follows its operands; a selection or `shift`
|
|
586
|
+
follows later mask changes; `invert_mask` works on a selection.
|
|
587
|
+
|
|
588
|
+
- Fix: MemoryView: a `CAFixlenString` exports as bytes and a frozen fixlen
|
|
589
|
+
array can be exported; `CATime`, `CACategorical` and `CAConstString` are
|
|
590
|
+
refused by `memory_view_available?` with the reason, instead of answering
|
|
591
|
+
`true` and failing.
|
|
592
|
+
|
|
593
|
+
- Fix: with carray-jit: two expressions that differ only in which operand an
|
|
594
|
+
operation reads no longer share a kernel, and a store whose destination
|
|
595
|
+
overlaps an operand is computed by CArray.
|
|
596
|
+
|
|
597
|
+
- Fix: for C extensions: a `CA_KERNEL_WRITE` walk over a view that holds a
|
|
598
|
+
cell more than once keeps the cells the kernel wrote; a walk left with
|
|
599
|
+
`break` writes back its slab; writes through a `CAGrid`, `CAWindow` or
|
|
600
|
+
`CAShift` over a view reach the array; the sweep engine and paired walks
|
|
601
|
+
read an argument sharing the output's memory as it was; a view class
|
|
602
|
+
that is not registered with `ca_iter_register_source_kind` is still
|
|
603
|
+
accepted. Rebuild the extension.
|
|
604
|
+
|
|
37
605
|
## 3.0.2
|
|
38
606
|
|
|
39
607
|
- New: `CArray::AddressBasis`, for a C extension whose code addresses cells
|
data/README.md
CHANGED
|
@@ -4,18 +4,17 @@ Ruby/CArray is an extension library for the multi-dimensional array class. It pr
|
|
|
4
4
|
|
|
5
5
|
## Status
|
|
6
6
|
|
|
7
|
-
3.0.x still moves: behavior can change between releases
|
|
7
|
+
3.0.x still moves: behavior can change between releases. 3.1 is the first release meant to be depended on. Until then, treat it as a place to try things out.
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
11
|
* Every array carries a per-element mask for missing values, respected by reductions and statistics
|
|
12
12
|
* Views compose without copying — a write through the outermost view reaches the source data
|
|
13
|
-
* MemoryView protocol on both sides: share buffers with other numerical libraries without copying
|
|
14
|
-
* Kernel-style iteration: run a Ruby block over each sub-array spanning the axes you choose
|
|
15
|
-
* Attach domain meaning (time, angle, quantity with units…) without changing storage — a Face
|
|
13
|
+
* [MemoryView protocol](guides/users/15_memory_view.md) on both sides: share buffers with other numerical libraries without copying
|
|
16
14
|
* Define your own array class in pure Ruby while keeping the full CArray interface
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* Kernel-style iteration: run a Ruby block over each sub-array spanning the axes you choose
|
|
16
|
+
* Faces: array types for time, strings and categories, with methods of their own on top of everything CArray does
|
|
17
|
+
* Comes with a DataFrame ([`CAFrame`](guides/dataframe/README.md)) whose columns are plain CArrays, so masks and views keep working on them
|
|
19
18
|
|
|
20
19
|
Each of these is shown, briefly and with a runnable example, in [A tour of the features](docs/FeatureTour.md).
|
|
21
20
|
|
|
@@ -120,6 +119,7 @@ b.strip_mask(Float::NAN).sum(axis: 0)
|
|
|
120
119
|
* [Views](guides/users/06_views.md) — referring to data without copying
|
|
121
120
|
* [Reduction and statistics](guides/users/04_reduction_and_statistics.md) — summaries, whole or per axis
|
|
122
121
|
* [Masks and missing values](guides/users/05_masks.md) — undefined elements, and how calculations treat them
|
|
122
|
+
* [Data frames](guides/dataframe/README.md) — tables of named columns, each column a CArray
|
|
123
123
|
|
|
124
124
|
## Contributing
|
|
125
125
|
|
data/carray.gemspec
CHANGED