polars-df 0.25.1 → 0.26.1

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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -1
  3. data/Cargo.lock +278 -106
  4. data/Cargo.toml +0 -3
  5. data/LICENSE.txt +1 -1
  6. data/README.md +7 -3
  7. data/ext/polars/Cargo.toml +18 -18
  8. data/ext/polars/src/catalog/unity.rs +15 -20
  9. data/ext/polars/src/conversion/any_value.rs +25 -24
  10. data/ext/polars/src/conversion/chunked_array.rs +58 -56
  11. data/ext/polars/src/conversion/datetime.rs +58 -7
  12. data/ext/polars/src/conversion/mod.rs +205 -142
  13. data/ext/polars/src/dataframe/export.rs +15 -12
  14. data/ext/polars/src/dataframe/general.rs +5 -4
  15. data/ext/polars/src/dataframe/map.rs +6 -4
  16. data/ext/polars/src/error.rs +1 -1
  17. data/ext/polars/src/expr/array.rs +0 -24
  18. data/ext/polars/src/expr/datatype.rs +3 -2
  19. data/ext/polars/src/expr/datetime.rs +4 -4
  20. data/ext/polars/src/expr/general.rs +27 -15
  21. data/ext/polars/src/expr/list.rs +0 -26
  22. data/ext/polars/src/functions/business.rs +2 -2
  23. data/ext/polars/src/functions/io.rs +4 -3
  24. data/ext/polars/src/functions/lazy.rs +58 -46
  25. data/ext/polars/src/functions/meta.rs +6 -5
  26. data/ext/polars/src/functions/mod.rs +0 -1
  27. data/ext/polars/src/functions/utils.rs +4 -2
  28. data/ext/polars/src/interop/arrow/mod.rs +4 -2
  29. data/ext/polars/src/interop/arrow/to_rb.rs +17 -12
  30. data/ext/polars/src/interop/numo/to_numo_series.rs +26 -25
  31. data/ext/polars/src/io/scan_options.rs +6 -3
  32. data/ext/polars/src/io/sink_options.rs +2 -0
  33. data/ext/polars/src/lazyframe/general.rs +32 -16
  34. data/ext/polars/src/lazyframe/optflags.rs +2 -1
  35. data/ext/polars/src/lib.rs +21 -37
  36. data/ext/polars/src/map/lazy.rs +5 -2
  37. data/ext/polars/src/map/series.rs +19 -18
  38. data/ext/polars/src/on_startup.rs +16 -7
  39. data/ext/polars/src/ruby/capsule.rs +27 -0
  40. data/ext/polars/src/ruby/mod.rs +1 -0
  41. data/ext/polars/src/ruby/numo.rs +3 -4
  42. data/ext/polars/src/ruby/rb_modules.rs +2 -4
  43. data/ext/polars/src/ruby/ruby_udf.rs +7 -9
  44. data/ext/polars/src/ruby/utils.rs +12 -1
  45. data/ext/polars/src/series/aggregation.rs +13 -1
  46. data/ext/polars/src/series/export.rs +38 -38
  47. data/ext/polars/src/series/general.rs +4 -3
  48. data/ext/polars/src/series/map.rs +3 -2
  49. data/ext/polars/src/series/scatter.rs +4 -4
  50. data/ext/polars/src/utils.rs +31 -7
  51. data/lib/polars/array_expr.rb +23 -7
  52. data/lib/polars/array_name_space.rb +16 -2
  53. data/lib/polars/binary_name_space.rb +32 -0
  54. data/lib/polars/data_frame.rb +83 -11
  55. data/lib/polars/date_time_expr.rb +91 -3
  56. data/lib/polars/date_time_name_space.rb +7 -1
  57. data/lib/polars/expr.rb +122 -44
  58. data/lib/polars/functions/aggregation/horizontal.rb +4 -4
  59. data/lib/polars/functions/business.rb +2 -2
  60. data/lib/polars/functions/eager.rb +80 -7
  61. data/lib/polars/functions/lazy.rb +5 -2
  62. data/lib/polars/iceberg_dataset.rb +81 -14
  63. data/lib/polars/io/csv.rb +27 -5
  64. data/lib/polars/io/delta.rb +4 -0
  65. data/lib/polars/io/ipc.rb +1 -1
  66. data/lib/polars/io/lines.rb +4 -4
  67. data/lib/polars/io/sink_options.rb +4 -2
  68. data/lib/polars/lazy_frame.rb +97 -14
  69. data/lib/polars/list_expr.rb +21 -7
  70. data/lib/polars/list_name_space.rb +16 -2
  71. data/lib/polars/query_opt_flags.rb +22 -5
  72. data/lib/polars/schema.rb +9 -0
  73. data/lib/polars/selectors.rb +1 -1
  74. data/lib/polars/series.rb +106 -19
  75. data/lib/polars/sql_context.rb +2 -2
  76. data/lib/polars/string_cache.rb +19 -72
  77. data/lib/polars/string_expr.rb +1 -7
  78. data/lib/polars/string_name_space.rb +1 -7
  79. data/lib/polars/utils/construction/series.rb +8 -3
  80. data/lib/polars/utils/convert.rb +16 -6
  81. data/lib/polars/utils/parse.rb +7 -0
  82. data/lib/polars/utils/reduce_balanced.rb +43 -0
  83. data/lib/polars/utils/various.rb +5 -0
  84. data/lib/polars/version.rb +1 -1
  85. data/lib/polars.rb +5 -1
  86. metadata +4 -17
  87. data/ext/polars/src/functions/string_cache.rs +0 -24
@@ -11,6 +11,13 @@ module Polars
11
11
 
12
12
  # Evaluate whether all boolean values in a list are true.
13
13
  #
14
+ # @param ignore_nulls [Boolean]
15
+ # * If set to `true` (default), null values are ignored. If there
16
+ # are no non-null values, the output is `true`.
17
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
18
+ # if the column contains any null values and no `false` values,
19
+ # the output is null.
20
+ #
14
21
  # @return [Expr]
15
22
  #
16
23
  # @example
@@ -32,12 +39,19 @@ module Polars
32
39
  # # │ [] ┆ true │
33
40
  # # │ null ┆ null │
34
41
  # # └────────────────┴───────┘
35
- def all
36
- Utils.wrap_expr(_rbexpr.list_all)
42
+ def all(ignore_nulls: true)
43
+ agg(F.element.all(ignore_nulls: ignore_nulls))
37
44
  end
38
45
 
39
46
  # Evaluate whether any boolean value in a list is true.
40
47
  #
48
+ # @param ignore_nulls [Boolean]
49
+ # * If set to `true` (default), null values are ignored. If there
50
+ # are no non-null values, the output is `false`.
51
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
52
+ # if the column contains any null values and no `true` values,
53
+ # the output is null.
54
+ #
41
55
  # @return [Expr]
42
56
  #
43
57
  # @example
@@ -59,8 +73,8 @@ module Polars
59
73
  # # │ [] ┆ false │
60
74
  # # │ null ┆ null │
61
75
  # # └────────────────┴───────┘
62
- def any
63
- Utils.wrap_expr(_rbexpr.list_any)
76
+ def any(ignore_nulls: true)
77
+ agg(F.element.any(ignore_nulls: ignore_nulls))
64
78
  end
65
79
 
66
80
  # Get the length of the arrays as `:u32`.
@@ -367,7 +381,7 @@ module Polars
367
381
  # # │ [2, 1, 9] │
368
382
  # # └───────────┘
369
383
  def reverse
370
- Utils.wrap_expr(_rbexpr.list_reverse)
384
+ eval(F.element.reverse)
371
385
  end
372
386
 
373
387
  # Get the unique/distinct values in the list.
@@ -391,7 +405,7 @@ module Polars
391
405
  # # │ [1, 2] │
392
406
  # # └───────────┘
393
407
  def unique(maintain_order: false)
394
- Utils.wrap_expr(_rbexpr.list_unique(maintain_order))
408
+ eval(F.element.unique(maintain_order: maintain_order))
395
409
  end
396
410
 
397
411
  # Count the number of unique values in every sub-lists.
@@ -416,7 +430,7 @@ module Polars
416
430
  # # │ [2, 3, 4] ┆ 3 │
417
431
  # # └───────────┴──────────┘
418
432
  def n_unique
419
- Utils.wrap_expr(_rbexpr.list_n_unique)
433
+ agg(F.element.n_unique)
420
434
  end
421
435
 
422
436
  # Concat the arrays in a Series dtype List in linear time.
@@ -12,6 +12,13 @@ module Polars
12
12
 
13
13
  # Evaluate whether all boolean values in a list are true.
14
14
  #
15
+ # @param ignore_nulls [Boolean]
16
+ # * If set to `true` (default), null values are ignored. If there
17
+ # are no non-null values, the output is `true`.
18
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
19
+ # if the column contains any null values and no `false` values,
20
+ # the output is null.
21
+ #
15
22
  # @return [Series]
16
23
  #
17
24
  # @example
@@ -31,12 +38,19 @@ module Polars
31
38
  # # true
32
39
  # # null
33
40
  # # ]
34
- def all
41
+ def all(ignore_nulls: true)
35
42
  super
36
43
  end
37
44
 
38
45
  # Evaluate whether any boolean value in a list is true.
39
46
  #
47
+ # @param ignore_nulls [Boolean]
48
+ # * If set to `true` (default), null values are ignored. If there
49
+ # are no non-null values, the output is `false`.
50
+ # * If set to `false`, [Kleene logic](https://en.wikipedia.org/wiki/Three-valued_logic) is used to deal with nulls:
51
+ # if the column contains any null values and no `true` values,
52
+ # the output is null.
53
+ #
40
54
  # @return [Series]
41
55
  #
42
56
  # @example
@@ -56,7 +70,7 @@ module Polars
56
70
  # # false
57
71
  # # null
58
72
  # # ]
59
- def any
73
+ def any(ignore_nulls: true)
60
74
  super
61
75
  end
62
76
 
@@ -18,7 +18,8 @@ module Polars
18
18
  cluster_with_columns: nil,
19
19
  collapse_joins: nil,
20
20
  check_order_observe: nil,
21
- fast_projection: nil
21
+ fast_projection: nil,
22
+ sort_collapse: nil
22
23
  )
23
24
  self._rboptflags = RbOptFlags.default
24
25
  update(
@@ -31,7 +32,8 @@ module Polars
31
32
  cluster_with_columns: cluster_with_columns,
32
33
  collapse_joins: collapse_joins,
33
34
  check_order_observe: check_order_observe,
34
- fast_projection: fast_projection
35
+ fast_projection: fast_projection,
36
+ sort_collapse: sort_collapse
35
37
  )
36
38
  end
37
39
 
@@ -46,7 +48,8 @@ module Polars
46
48
  cluster_with_columns: nil,
47
49
  collapse_joins: nil,
48
50
  check_order_observe: nil,
49
- fast_projection: nil
51
+ fast_projection: nil,
52
+ sort_collapse: nil
50
53
  )
51
54
  optflags = QueryOptFlags.new
52
55
  optflags.no_optimizations
@@ -60,7 +63,8 @@ module Polars
60
63
  cluster_with_columns: cluster_with_columns,
61
64
  collapse_joins: collapse_joins,
62
65
  check_order_observe: check_order_observe,
63
- fast_projection: fast_projection
66
+ fast_projection: fast_projection,
67
+ sort_collapse: sort_collapse
64
68
  )
65
69
  end
66
70
 
@@ -74,7 +78,8 @@ module Polars
74
78
  cluster_with_columns: nil,
75
79
  collapse_joins: nil,
76
80
  check_order_observe: nil,
77
- fast_projection: nil
81
+ fast_projection: nil,
82
+ sort_collapse: nil
78
83
  )
79
84
  if !predicate_pushdown.nil?
80
85
  self.predicate_pushdown = predicate_pushdown
@@ -112,6 +117,9 @@ module Polars
112
117
  if !fast_projection.nil?
113
118
  self.fast_projection = fast_projection
114
119
  end
120
+ if !sort_collapse.nil?
121
+ self.sort_collapse = sort_collapse
122
+ end
115
123
 
116
124
  self
117
125
  end
@@ -211,6 +219,15 @@ module Polars
211
219
  _rboptflags.fast_projection = value
212
220
  end
213
221
 
222
+ # Collapse sequential sort nodes into a single sort node.
223
+ def sort_collapse
224
+ _rboptflags.sort_collapse
225
+ end
226
+
227
+ def sort_collapse=(value)
228
+ _rboptflags.sort_collapse = value
229
+ end
230
+
214
231
  def to_s
215
232
  <<~STR
216
233
  QueryOptFlags {
data/lib/polars/schema.rb CHANGED
@@ -71,6 +71,15 @@ module Polars
71
71
  @schema.values
72
72
  end
73
73
 
74
+ # Convert the schema to a nanoarrow schema.
75
+ #
76
+ # @return [Nanoarrow::Schema]
77
+ def to_arrow
78
+ require "nanoarrow"
79
+
80
+ Nanoarrow::Schema.new(self)
81
+ end
82
+
74
83
  # Get the number of schema entries.
75
84
  #
76
85
  # @return [Integer]
@@ -264,7 +264,7 @@ module Polars
264
264
  re_alpha = ascii_only ? "a-zA-Z" : "\\p{Alphabetic}"
265
265
  re_digit = ascii_only ? "0-9" : "\\d"
266
266
  re_space = ignore_spaces ? " " : ""
267
- return Selector._from_rbselector(
267
+ Selector._from_rbselector(
268
268
  RbSelector.matches("^[#{re_alpha}#{re_digit}#{re_space}]+$")
269
269
  )
270
270
  end
data/lib/polars/series.rb CHANGED
@@ -73,6 +73,8 @@ module Polars
73
73
  self._s = Utils.dataframe_to_rbseries(
74
74
  original_name, values, dtype: dtype, strict: strict
75
75
  )
76
+ elsif values.respond_to?(:arrow_c_stream)
77
+ self._s = RbSeries.from_arrow_c_stream(values)
76
78
  else
77
79
  raise TypeError, "Series constructor called with unsupported type; got #{values.class.name}"
78
80
  end
@@ -496,6 +498,11 @@ module Polars
496
498
  end
497
499
  end
498
500
 
501
+ # @private
502
+ def arrow_c_stream
503
+ _s.arrow_c_stream
504
+ end
505
+
499
506
  # Return the Series as a scalar, or return the element at the given index.
500
507
  #
501
508
  # If no index is provided, this is equivalent to `s[0]`, with a check
@@ -1184,7 +1191,7 @@ module Polars
1184
1191
  # s.cut([-1, 1], labels: ["a", "b", "c"])
1185
1192
  # # =>
1186
1193
  # # shape: (5,)
1187
- # # Series: 'foo' [cat]
1194
+ # # Series: 'foo' [enum]
1188
1195
  # # [
1189
1196
  # # "a"
1190
1197
  # # "a"
@@ -1201,7 +1208,7 @@ module Polars
1201
1208
  # # ┌─────┬─────────────┬────────────┐
1202
1209
  # # │ foo ┆ break_point ┆ category │
1203
1210
  # # │ --- ┆ --- ┆ --- │
1204
- # # │ i64 ┆ f64 ┆ cat
1211
+ # # │ i64 ┆ f64 ┆ enum
1205
1212
  # # ╞═════╪═════════════╪════════════╡
1206
1213
  # # │ -2 ┆ -1.0 ┆ (-inf, -1] │
1207
1214
  # # │ -1 ┆ -1.0 ┆ (-inf, -1] │
@@ -1515,13 +1522,7 @@ module Polars
1515
1522
  # b = Polars::Series.new([0.65, 0.10, 0.25])
1516
1523
  # b.entropy(normalize: true)
1517
1524
  # # => 0.8568409950394724
1518
- def entropy(base: Math::E, normalize: nil)
1519
- # TODO update
1520
- if normalize.nil?
1521
- warn "The default `normalize` for `entropy` method will change from `false` to `true` in a future version"
1522
- normalize = false
1523
- end
1524
-
1525
+ def entropy(base: Math::E, normalize: true)
1525
1526
  Polars.select(Polars.lit(self).entropy(base: base, normalize: normalize)).to_series[0]
1526
1527
  end
1527
1528
 
@@ -2391,6 +2392,11 @@ module Polars
2391
2392
  #
2392
2393
  # @param indices [Array]
2393
2394
  # Index location used for selection.
2395
+ # @param null_on_oob [Boolean]
2396
+ # Behavior if an index is out of bounds:
2397
+ #
2398
+ # - true -> set the result to null
2399
+ # - false -> raise an error
2394
2400
  #
2395
2401
  # @return [Series]
2396
2402
  #
@@ -2404,7 +2410,7 @@ module Polars
2404
2410
  # # 2
2405
2411
  # # 4
2406
2412
  # # ]
2407
- def gather(indices)
2413
+ def gather(indices, null_on_oob: false)
2408
2414
  super
2409
2415
  end
2410
2416
 
@@ -2441,14 +2447,23 @@ module Polars
2441
2447
 
2442
2448
  # Check if the Series is empty.
2443
2449
  #
2450
+ # @param ignore_nulls [Boolean]
2451
+ # If true a series containing only nulls will also be considered empty.
2452
+ # The default is false.
2453
+ #
2444
2454
  # @return [Boolean]
2445
2455
  #
2446
2456
  # @example
2447
2457
  # s = Polars::Series.new("a", [])
2448
2458
  # s.is_empty
2449
2459
  # # => true
2450
- def is_empty
2451
- len == 0
2460
+ def is_empty(ignore_nulls: false)
2461
+ if ignore_nulls
2462
+ msg = "the `ignore_nulls` parameter of `Series.is_empty()` is considered unstable."
2463
+ Utils.issue_unstable_warning(msg)
2464
+ end
2465
+
2466
+ _s.is_empty(ignore_nulls: ignore_nulls)
2452
2467
  end
2453
2468
  alias_method :empty?, :is_empty
2454
2469
 
@@ -3106,6 +3121,8 @@ module Polars
3106
3121
  # # Numo::Int64#shape=[3]
3107
3122
  # # [1, 2, 3]
3108
3123
  def to_numo
3124
+ require "numo/narray"
3125
+
3109
3126
  if dtype.temporal?
3110
3127
  Numo::RObject.cast(to_a)
3111
3128
  else
@@ -3113,6 +3130,15 @@ module Polars
3113
3130
  end
3114
3131
  end
3115
3132
 
3133
+ # Return the underlying Arrow array.
3134
+ #
3135
+ # @return [Nanoarrow::Array]
3136
+ def to_arrow
3137
+ require "nanoarrow"
3138
+
3139
+ Nanoarrow::Array.new(self)
3140
+ end
3141
+
3116
3142
  # Set masked values.
3117
3143
  #
3118
3144
  # @param filter [Series]
@@ -3391,6 +3417,51 @@ module Polars
3391
3417
  super
3392
3418
  end
3393
3419
 
3420
+ # Truncate numeric data toward zero to `decimals` number of decimal places.
3421
+ #
3422
+ # @param decimals [Integer]
3423
+ # Number of decimal places to truncate to.
3424
+ #
3425
+ # @return [Series]
3426
+ #
3427
+ # @note
3428
+ # Truncation discards the fractional part beyond the given number of decimals.
3429
+ # For example, when rounding to 0 decimals 0.25, -0.25, 0.99, and -0.99 will
3430
+ # all round to 0. When rounding to 1 decimal 1.9999 rounds to 1.9 and -1.9999
3431
+ # rounds to -1.9. There is no tiebreak behaviour at midpoint values as there
3432
+ # is with :meth:`round` so 0.5 and -0.5 will also round to 0 when decimals=1.
3433
+ #
3434
+ # @note
3435
+ # This method performs numeric truncation. For truncating temporal
3436
+ # data (dates/datetimes), use :func:`Series.dt.truncate` instead.
3437
+ #
3438
+ # @example
3439
+ # s = Polars::Series.new("a", [1.12345, 2.56789, 3.991234])
3440
+ # s.truncate(2)
3441
+ # # =>
3442
+ # # shape: (3,)
3443
+ # # Series: 'a' [f64]
3444
+ # # [
3445
+ # # 1.12
3446
+ # # 2.56
3447
+ # # 3.99
3448
+ # # ]
3449
+ #
3450
+ # @example
3451
+ # s = Polars::Series.new("a", [-1.78, 2.56, -3.99])
3452
+ # s.truncate(0)
3453
+ # # =>
3454
+ # # shape: (3,)
3455
+ # # Series: 'a' [f64]
3456
+ # # [
3457
+ # # -1.0
3458
+ # # 2.0
3459
+ # # -3.0
3460
+ # # ]
3461
+ def truncate(decimals = 0)
3462
+ super
3463
+ end
3464
+
3394
3465
  # Round underlying floating point data by `decimals` digits.
3395
3466
  #
3396
3467
  # The default rounding mode is "half to even" (also known as "bankers' rounding").
@@ -4327,7 +4398,7 @@ module Polars
4327
4398
  def rolling_sum_by(
4328
4399
  by,
4329
4400
  window_size,
4330
- min_samples: 1,
4401
+ min_samples: 0,
4331
4402
  closed: "right"
4332
4403
  )
4333
4404
  super
@@ -5185,8 +5256,8 @@ module Polars
5185
5256
  # # shape: (2,)
5186
5257
  # # Series: 'a' [i64]
5187
5258
  # # [
5188
- # # 5
5189
5259
  # # 2
5260
+ # # 5
5190
5261
  # # ]
5191
5262
  def sample(
5192
5263
  n: nil,
@@ -5299,13 +5370,18 @@ module Polars
5299
5370
  super
5300
5371
  end
5301
5372
 
5302
- # Reinterpret the underlying bits as a signed/unsigned integer.
5373
+ # Reinterpret the underlying bits as a signed/unsigned integer or float.
5303
5374
  #
5304
- # This operation is only allowed for 64bit integers. For lower bits integers,
5305
- # you can safely use that cast operation.
5375
+ # This operation is only allowed for numeric types of the same size.
5376
+ # For lower bits numbers, you can safely use the cast operation.
5377
+ #
5378
+ # Either `signed` or `dtype` can be specified.
5306
5379
  #
5307
5380
  # @param signed [Boolean]
5308
- # If true, reinterpret as `Polars::Int64`. Otherwise, reinterpret as `Polars::UInt64`.
5381
+ # If true, reinterpret as signed integer. Otherwise, reinterpret
5382
+ # as unsigned integer.
5383
+ # @param dtype [Object]
5384
+ # DataType to reinterpret to.
5309
5385
  #
5310
5386
  # @return [Series]
5311
5387
  #
@@ -5320,7 +5396,18 @@ module Polars
5320
5396
  # # 18446744073709551614
5321
5397
  # # 3
5322
5398
  # # ]
5323
- def reinterpret(signed: true)
5399
+ #
5400
+ # @example
5401
+ # s.reinterpret(dtype: Polars::Int64)
5402
+ # # =>
5403
+ # # shape: (3,)
5404
+ # # Series: 'a' [i64]
5405
+ # # [
5406
+ # # -1152921504606846976
5407
+ # # -2
5408
+ # # 3
5409
+ # # ]
5410
+ def reinterpret(signed: nil, dtype: nil)
5324
5411
  super
5325
5412
  end
5326
5413
 
@@ -73,11 +73,11 @@ module Polars
73
73
  # ctx.execute(
74
74
  # "
75
75
  # SELECT
76
- # MAX(release_year / 10) * 10 AS decade,
76
+ # MAX(release_year // 10) * 10 AS decade,
77
77
  # SUM(gross) AS total_gross,
78
78
  # COUNT(title) AS n_films,
79
79
  # FROM films
80
- # GROUP BY (release_year / 10) -- decade
80
+ # GROUP BY (release_year // 10) -- decade
81
81
  # ORDER BY total_gross DESC
82
82
  # ",
83
83
  # eager: true
@@ -1,30 +1,11 @@
1
1
  module Polars
2
- # Class for enabling and disabling the global string cache.
2
+ # Does nothing.
3
3
  #
4
- # @example Construct two Series using the same global string cache.
5
- # s1 = nil
6
- # s2 = nil
7
- # Polars::StringCache.new do
8
- # s1 = Polars::Series.new("color", ["red", "green", "red"], dtype: Polars::Categorical)
9
- # s2 = Polars::Series.new("color", ["blue", "red", "green"], dtype: Polars::Categorical)
10
- # end
11
- #
12
- # @example As both Series are constructed under the same global string cache, they can be concatenated.
13
- # Polars.concat([s1, s2])
14
- # # =>
15
- # # shape: (6,)
16
- # # Series: 'color' [cat]
17
- # # [
18
- # # "red"
19
- # # "green"
20
- # # "red"
21
- # # "blue"
22
- # # "red"
23
- # # "green"
24
- # # ]
4
+ # @deprecated
5
+ # The string cache was used to maintain the mapping for the Categorical
6
+ # dtype, this is now done through `Polars::Categories`.
25
7
  class StringCache
26
8
  def initialize(&block)
27
- RbStringCacheHolder.hold(&block)
28
9
  end
29
10
  end
30
11
 
@@ -33,69 +14,35 @@ module Polars
33
14
  end
34
15
 
35
16
  module Functions
36
- # Enable the global string cache.
17
+ # Does nothing.
37
18
  #
38
- # `Categorical` columns created under the same global string cache have
39
- # the same underlying physical value when string values are equal. This allows the
40
- # columns to be concatenated or used in a join operation, for example.
19
+ # @deprecated
20
+ # The string cache was used to maintain the mapping for the Categorical
21
+ # dtype, this is now done through `Polars::Categories`.
41
22
  #
42
23
  # @return [nil]
43
- #
44
- # @example Construct two Series using the same global string cache.
45
- # Polars.enable_string_cache
46
- # s1 = Polars::Series.new("color", ["red", "green", "red"], dtype: Polars::Categorical)
47
- # s2 = Polars::Series.new("color", ["blue", "red", "green"], dtype: Polars::Categorical)
48
- # Polars.disable_string_cache
49
- #
50
- # @example As both Series are constructed under the same global string cache, they can be concatenated.
51
- # Polars.concat([s1, s2])
52
- # # =>
53
- # # shape: (6,)
54
- # # Series: 'color' [cat]
55
- # # [
56
- # # "red"
57
- # # "green"
58
- # # "red"
59
- # # "blue"
60
- # # "red"
61
- # # "green"
62
- # # ]
63
24
  def enable_string_cache
64
- Plr.enable_string_cache
65
25
  end
66
26
 
67
- # Disable and clear the global string cache.
27
+ # Does nothing.
68
28
  #
69
- # @return [nil]
29
+ # @deprecated
30
+ # The string cache was used to maintain the mapping for the Categorical
31
+ # dtype, this is now done through `Polars::Categories`.
70
32
  #
71
- # @example Construct two Series using the same global string cache.
72
- # Polars.enable_string_cache
73
- # s1 = Polars::Series.new("color", ["red", "green", "red"], dtype: Polars::Categorical)
74
- # s2 = Polars::Series.new("color", ["blue", "red", "green"], dtype: Polars::Categorical)
75
- # Polars.disable_string_cache
76
- #
77
- # @example As both Series are constructed under the same global string cache, they can be concatenated.
78
- # Polars.concat([s1, s2])
79
- # # =>
80
- # # shape: (6,)
81
- # # Series: 'color' [cat]
82
- # # [
83
- # # "red"
84
- # # "green"
85
- # # "red"
86
- # # "blue"
87
- # # "red"
88
- # # "green"
89
- # # ]
33
+ # @return [nil]
90
34
  def disable_string_cache
91
- Plr.disable_string_cache
92
35
  end
93
36
 
94
- # Check whether the global string cache is enabled.
37
+ # Always returns true.
38
+ #
39
+ # @deprecated
40
+ # The string cache was used to maintain the mapping for the Categorical
41
+ # dtype, this is now done through `Polars::Categories`.
95
42
  #
96
43
  # @return [Boolean]
97
44
  def using_string_cache
98
- Plr.using_string_cache
45
+ true
99
46
  end
100
47
  end
101
48
  end
@@ -378,13 +378,7 @@ module Polars
378
378
  # # ╞══════╡
379
379
  # # │ null │
380
380
  # # └──────┘
381
- def join(delimiter = nil, ignore_nulls: true)
382
- # TODO update
383
- if delimiter.nil?
384
- warn "The default `delimiter` for `join` method will change from `-` to empty string in a future version"
385
- delimiter = "-"
386
- end
387
-
381
+ def join(delimiter = "", ignore_nulls: true)
388
382
  Utils.wrap_expr(_rbexpr.str_join(delimiter, ignore_nulls))
389
383
  end
390
384
 
@@ -1494,13 +1494,7 @@ module Polars
1494
1494
  # # [
1495
1495
  # # null
1496
1496
  # # ]
1497
- def join(delimiter = nil, ignore_nulls: true)
1498
- # TODO update
1499
- if delimiter.nil?
1500
- warn "The default `delimiter` for `join` method will change from `-` to empty string in a future version"
1501
- delimiter = "-"
1502
- end
1503
-
1497
+ def join(delimiter = "", ignore_nulls: true)
1504
1498
  super
1505
1499
  end
1506
1500
 
@@ -313,12 +313,17 @@ module Polars
313
313
  TrueClass => RbSeries.method(:new_opt_bool),
314
314
  FalseClass => RbSeries.method(:new_opt_bool),
315
315
  Integer => RbSeries.method(:new_opt_i64),
316
- String => RbSeries.method(:new_str),
317
- BigDecimal => RbSeries.method(:new_decimal)
316
+ ::String => RbSeries.method(:new_str)
318
317
  }
319
318
 
320
319
  def self.rb_type_to_constructor(dtype)
321
- RB_TYPE_TO_CONSTRUCTOR.fetch(dtype, RbSeries.method(:new_object))
320
+ RB_TYPE_TO_CONSTRUCTOR.fetch(dtype) do
321
+ if defined?(::BigDecimal) && dtype == ::BigDecimal
322
+ RbSeries.method(:new_decimal)
323
+ else
324
+ RbSeries.method(:new_object)
325
+ end
326
+ end
322
327
  end
323
328
 
324
329
  def self.numo_values_and_dtype(values)
@@ -63,19 +63,24 @@ module Polars
63
63
  end
64
64
 
65
65
  def self._to_ruby_datetime(value, time_unit = "ns", time_zone = nil)
66
- if time_zone.nil? || time_zone == "" || time_zone == "UTC"
66
+ utc_time =
67
67
  if time_unit == "ns"
68
- ::Time.at(value / 1000000000, value % 1000000000, :nsec).utc
68
+ ::Time.at(value / 1_000_000_000, value % 1_000_000_000, :nsec).utc
69
69
  elsif time_unit == "us"
70
- ::Time.at(value / 1000000, value % 1000000, :usec).utc
70
+ ::Time.at(value / 1_000_000, value % 1_000_000, :usec).utc
71
71
  elsif time_unit == "ms"
72
- ::Time.at(value / 1000, value % 1000, :millisecond).utc
72
+ ::Time.at(value / 1_000, value % 1_000, :millisecond).utc
73
73
  else
74
74
  raise ArgumentError, "time_unit must be one of {{'ns', 'us', 'ms'}}, got #{time_unit}"
75
75
  end
76
- else
77
- raise Todo
76
+ return utc_time if time_zone.nil?
77
+
78
+ unless defined?(::TZInfo)
79
+ # TODO improve error message
80
+ require "tzinfo"
78
81
  end
82
+
83
+ utc_time.getlocal(::TZInfo::Timezone.get(time_zone))
79
84
  end
80
85
 
81
86
  def self._to_ruby_duration(value, time_unit = "ns")
@@ -91,6 +96,11 @@ module Polars
91
96
  end
92
97
 
93
98
  def self._to_ruby_decimal(prec, value)
99
+ unless defined?(::BigDecimal)
100
+ # TODO improve error message
101
+ require "bigdecimal"
102
+ end
103
+
94
104
  BigDecimal(value, prec)
95
105
  end
96
106
  end