polars-df 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/Cargo.lock +270 -97
  4. data/LICENSE.txt +1 -1
  5. data/README.md +1 -3
  6. data/ext/polars/Cargo.toml +19 -18
  7. data/ext/polars/src/catalog/unity.rs +15 -20
  8. data/ext/polars/src/conversion/any_value.rs +53 -29
  9. data/ext/polars/src/conversion/chunked_array.rs +58 -56
  10. data/ext/polars/src/conversion/datetime.rs +58 -7
  11. data/ext/polars/src/conversion/mod.rs +200 -150
  12. data/ext/polars/src/dataframe/export.rs +15 -12
  13. data/ext/polars/src/dataframe/general.rs +25 -7
  14. data/ext/polars/src/dataframe/map.rs +6 -4
  15. data/ext/polars/src/error.rs +1 -1
  16. data/ext/polars/src/expr/array.rs +0 -24
  17. data/ext/polars/src/expr/datatype.rs +13 -3
  18. data/ext/polars/src/expr/datetime.rs +4 -4
  19. data/ext/polars/src/expr/general.rs +35 -15
  20. data/ext/polars/src/expr/list.rs +0 -26
  21. data/ext/polars/src/expr/rolling.rs +24 -0
  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 +65 -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/range.rs +13 -0
  28. data/ext/polars/src/functions/utils.rs +4 -2
  29. data/ext/polars/src/interop/arrow/mod.rs +4 -2
  30. data/ext/polars/src/interop/arrow/to_rb.rs +1 -1
  31. data/ext/polars/src/interop/numo/to_numo_series.rs +26 -25
  32. data/ext/polars/src/io/scan_options.rs +6 -3
  33. data/ext/polars/src/io/sink_options.rs +2 -0
  34. data/ext/polars/src/lazyframe/general.rs +243 -17
  35. data/ext/polars/src/lazyframe/optflags.rs +2 -1
  36. data/ext/polars/src/lib.rs +39 -35
  37. data/ext/polars/src/map/lazy.rs +5 -2
  38. data/ext/polars/src/map/series.rs +19 -18
  39. data/ext/polars/src/on_startup.rs +25 -6
  40. data/ext/polars/src/ruby/numo.rs +3 -4
  41. data/ext/polars/src/ruby/plan_callback.rs +1 -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/construction.rs +31 -50
  47. data/ext/polars/src/series/export.rs +33 -38
  48. data/ext/polars/src/series/general.rs +6 -6
  49. data/ext/polars/src/series/map.rs +3 -2
  50. data/ext/polars/src/series/scatter.rs +4 -4
  51. data/ext/polars/src/utils.rs +31 -7
  52. data/lib/polars/array_expr.rb +23 -7
  53. data/lib/polars/array_name_space.rb +16 -2
  54. data/lib/polars/binary_name_space.rb +32 -0
  55. data/lib/polars/collect_batches.rb +4 -0
  56. data/lib/polars/data_frame.rb +144 -11
  57. data/lib/polars/data_type_group.rb +5 -0
  58. data/lib/polars/date_time_expr.rb +91 -3
  59. data/lib/polars/date_time_name_space.rb +7 -1
  60. data/lib/polars/expr.rb +247 -44
  61. data/lib/polars/functions/business.rb +2 -2
  62. data/lib/polars/functions/datatype.rb +30 -0
  63. data/lib/polars/functions/eager.rb +80 -7
  64. data/lib/polars/functions/lazy.rb +97 -2
  65. data/lib/polars/functions/range/linear_space.rb +118 -0
  66. data/lib/polars/io/csv.rb +27 -5
  67. data/lib/polars/io/database.rb +2 -3
  68. data/lib/polars/io/ipc.rb +2 -2
  69. data/lib/polars/io/lines.rb +172 -0
  70. data/lib/polars/io/parquet.rb +1 -1
  71. data/lib/polars/io/sink_options.rb +5 -2
  72. data/lib/polars/lazy_frame.rb +517 -14
  73. data/lib/polars/list_expr.rb +21 -7
  74. data/lib/polars/list_name_space.rb +16 -2
  75. data/lib/polars/query_opt_flags.rb +23 -5
  76. data/lib/polars/selectors.rb +2 -2
  77. data/lib/polars/series.rb +176 -19
  78. data/lib/polars/sql_context.rb +2 -2
  79. data/lib/polars/string_cache.rb +19 -72
  80. data/lib/polars/string_expr.rb +1 -7
  81. data/lib/polars/string_name_space.rb +1 -7
  82. data/lib/polars/utils/construction/series.rb +24 -39
  83. data/lib/polars/utils/convert.rb +16 -6
  84. data/lib/polars/utils/parse.rb +7 -0
  85. data/lib/polars/utils/reduce_balanced.rb +43 -0
  86. data/lib/polars/utils/various.rb +5 -0
  87. data/lib/polars/version.rb +1 -1
  88. data/lib/polars.rb +2 -1
  89. metadata +4 -17
  90. data/ext/polars/src/functions/string_cache.rs +0 -24
@@ -21,11 +21,6 @@ module Polars
21
21
  rb_temporal_types << ActiveSupport::TimeWithZone if defined?(ActiveSupport::TimeWithZone)
22
22
 
23
23
  value = get_first_non_none(values)
24
- if !value.nil?
25
- if value.is_a?(Hash) && dtype != Object
26
- return DataFrame.new(values).to_struct(name)._s
27
- end
28
- end
29
24
 
30
25
  if !dtype.nil? && is_polars_dtype(dtype) && !dtype.nested? && dtype != Unknown && ruby_dtype.nil?
31
26
  constructor = polars_type_to_constructor(dtype)
@@ -76,7 +71,7 @@ module Polars
76
71
  end
77
72
 
78
73
  return sequence_to_rbdf(
79
- values.map { |v| v.nil? ? empty : v },
74
+ data,
80
75
  schema: struct_schema,
81
76
  orient: "row",
82
77
  ).to_struct(name, invalid)
@@ -185,6 +180,11 @@ module Polars
185
180
  rb_type_to_constructor(value.class)
186
181
  end
187
182
 
183
+ if constructor == RbSeries.method(:new_object)
184
+ srs = RbSeries.new_from_any_values(name, values, strict)
185
+ return srs
186
+ end
187
+
188
188
  _construct_series_with_fallbacks(constructor, name, values, dtype, strict: strict)
189
189
  end
190
190
  end
@@ -293,52 +293,37 @@ module Polars
293
293
  Null => RbSeries.method(:new_null)
294
294
  }
295
295
 
296
- SYM_TYPE_TO_CONSTRUCTOR = {
297
- f32: RbSeries.method(:new_opt_f32),
298
- f64: RbSeries.method(:new_opt_f64),
299
- i8: RbSeries.method(:new_opt_i8),
300
- i16: RbSeries.method(:new_opt_i16),
301
- i32: RbSeries.method(:new_opt_i32),
302
- i64: RbSeries.method(:new_opt_i64),
303
- i128: RbSeries.method(:new_opt_i128),
304
- u8: RbSeries.method(:new_opt_u8),
305
- u16: RbSeries.method(:new_opt_u16),
306
- u32: RbSeries.method(:new_opt_u32),
307
- u64: RbSeries.method(:new_opt_u64),
308
- u128: RbSeries.method(:new_opt_u128),
309
- bool: RbSeries.method(:new_opt_bool),
310
- str: RbSeries.method(:new_str)
311
- }
312
-
313
296
  def self.polars_type_to_constructor(dtype)
314
297
  if dtype.is_a?(Array)
315
- lambda do |name, values, strict|
316
- RbSeries.new_array(dtype.width, dtype.inner, name, values, strict)
298
+ return lambda do |name, values, strict|
299
+ RbSeries.new_array(name, values, strict, dtype)
317
300
  end
318
- elsif dtype.is_a?(Class) && dtype < DataType
319
- POLARS_TYPE_TO_CONSTRUCTOR.fetch(dtype)
320
- elsif dtype.is_a?(DataType)
321
- POLARS_TYPE_TO_CONSTRUCTOR.fetch(dtype.class)
322
- else
323
- SYM_TYPE_TO_CONSTRUCTOR.fetch(dtype.to_sym)
324
301
  end
325
- rescue KeyError
326
- raise ArgumentError, "Cannot construct RbSeries for type #{dtype}."
302
+
303
+ begin
304
+ base_type = dtype.base_type
305
+ POLARS_TYPE_TO_CONSTRUCTOR.fetch(base_type)
306
+ rescue KeyError
307
+ raise ArgumentError, "Cannot construct RbSeries for type #{dtype}."
308
+ end
327
309
  end
328
310
 
329
311
  RB_TYPE_TO_CONSTRUCTOR = {
330
312
  Float => RbSeries.method(:new_opt_f64),
331
- Integer => RbSeries.method(:new_opt_i64),
332
313
  TrueClass => RbSeries.method(:new_opt_bool),
333
314
  FalseClass => RbSeries.method(:new_opt_bool),
334
- BigDecimal => RbSeries.method(:new_decimal),
335
- NilClass => RbSeries.method(:new_null)
315
+ Integer => RbSeries.method(:new_opt_i64),
316
+ ::String => RbSeries.method(:new_str)
336
317
  }
337
318
 
338
319
  def self.rb_type_to_constructor(dtype)
339
- RB_TYPE_TO_CONSTRUCTOR.fetch(dtype)
340
- rescue KeyError
341
- 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
342
327
  end
343
328
 
344
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
@@ -131,5 +131,12 @@ module Polars
131
131
 
132
132
  Plr.all_horizontal(predicates)
133
133
  end
134
+
135
+ def self._holidays_to_expr(holidays)
136
+ if !(holidays.is_a?(Expr) || holidays.is_a?(Series))
137
+ holidays = Series.new("", [holidays], strict: false, dtype: List.new(Date))
138
+ end
139
+ parse_into_expression(holidays, dtype: Date)
140
+ end
134
141
  end
135
142
  end
@@ -0,0 +1,43 @@
1
+ module Polars
2
+ module Utils
3
+ def self.reduce_balanced(function, iterable)
4
+ values = iterable.to_a
5
+
6
+ if values.empty?
7
+ msg = "reduce_balanced() of empty iterable"
8
+ raise TypeError, msg
9
+ end
10
+
11
+ if values.length == 1
12
+ return values.shift
13
+ end
14
+
15
+ stack = [[0, values.length]]
16
+
17
+ i = 0
18
+
19
+ while i < stack.length
20
+ offset, length = stack[i]
21
+ half = -(length / -2)
22
+
23
+ if length > 3
24
+ stack << [offset + half, length - half]
25
+ end
26
+
27
+ if length > 2
28
+ stack << [offset, half]
29
+ end
30
+
31
+ stack[i] = [offset, offset + half]
32
+
33
+ i += 1
34
+ end
35
+
36
+ stack.reverse.each do |idx_l, idx_r|
37
+ values[idx_l] = function.(values[idx_l], values[idx_r])
38
+ end
39
+
40
+ values[0]
41
+ end
42
+ end
43
+ end
@@ -31,6 +31,11 @@ module Polars
31
31
  val.is_a?(::Array) || (include_series && val.is_a?(Series))
32
32
  end
33
33
 
34
+ # Check if an object is a sequence of `tp`, only sniffing the first element.
35
+ def self.is_non_empty_sequence_of(obj, tp)
36
+ !obj.empty? && obj[0].is_a?(tp)
37
+ end
38
+
34
39
  def self.is_str_sequence(val, allow_str: false)
35
40
  if allow_str == false && val.is_a?(::String)
36
41
  false
@@ -1,4 +1,4 @@
1
1
  module Polars
2
2
  # @private
3
- VERSION = "0.25.0"
3
+ VERSION = "0.26.0"
4
4
  end
data/lib/polars.rb CHANGED
@@ -6,7 +6,6 @@ rescue LoadError
6
6
  end
7
7
 
8
8
  # stdlib
9
- require "bigdecimal"
10
9
  require "date"
11
10
  require "stringio"
12
11
 
@@ -69,6 +68,7 @@ require_relative "polars/io/delta"
69
68
  require_relative "polars/io/iceberg"
70
69
  require_relative "polars/io/ipc"
71
70
  require_relative "polars/io/json"
71
+ require_relative "polars/io/lines"
72
72
  require_relative "polars/io/ndjson"
73
73
  require_relative "polars/io/parquet"
74
74
  require_relative "polars/io/scan_options"
@@ -104,6 +104,7 @@ require_relative "polars/utils/construction/utils"
104
104
  require_relative "polars/utils/convert"
105
105
  require_relative "polars/utils/deprecation"
106
106
  require_relative "polars/utils/parse"
107
+ require_relative "polars/utils/reduce_balanced"
107
108
  require_relative "polars/utils/serde"
108
109
  require_relative "polars/utils/unstable"
109
110
  require_relative "polars/utils/various"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: polars-df
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -9,20 +9,6 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: bigdecimal
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '0'
19
- type: :runtime
20
- prerelease: false
21
- version_requirements: !ruby/object:Gem::Requirement
22
- requirements:
23
- - - ">="
24
- - !ruby/object:Gem::Version
25
- version: '0'
26
12
  - !ruby/object:Gem::Dependency
27
13
  name: rb_sys
28
14
  requirement: !ruby/object:Gem::Requirement
@@ -97,7 +83,6 @@ files:
97
83
  - ext/polars/src/functions/mod.rs
98
84
  - ext/polars/src/functions/random.rs
99
85
  - ext/polars/src/functions/range.rs
100
- - ext/polars/src/functions/string_cache.rs
101
86
  - ext/polars/src/functions/strings.rs
102
87
  - ext/polars/src/functions/utils.rs
103
88
  - ext/polars/src/functions/whenthen.rs
@@ -216,6 +201,7 @@ files:
216
201
  - lib/polars/io/iceberg.rb
217
202
  - lib/polars/io/ipc.rb
218
203
  - lib/polars/io/json.rb
204
+ - lib/polars/io/lines.rb
219
205
  - lib/polars/io/ndjson.rb
220
206
  - lib/polars/io/parquet.rb
221
207
  - lib/polars/io/scan_options.rb
@@ -251,6 +237,7 @@ files:
251
237
  - lib/polars/utils/convert.rb
252
238
  - lib/polars/utils/deprecation.rb
253
239
  - lib/polars/utils/parse.rb
240
+ - lib/polars/utils/reduce_balanced.rb
254
241
  - lib/polars/utils/serde.rb
255
242
  - lib/polars/utils/unstable.rb
256
243
  - lib/polars/utils/various.rb
@@ -275,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
275
262
  - !ruby/object:Gem::Version
276
263
  version: '0'
277
264
  requirements: []
278
- rubygems_version: 4.0.3
265
+ rubygems_version: 4.0.13
279
266
  specification_version: 4
280
267
  summary: Blazingly fast DataFrames for Ruby
281
268
  test_files: []
@@ -1,24 +0,0 @@
1
- use crate::RbResult;
2
- use magnus::{Ruby, Value};
3
-
4
- pub fn enable_string_cache() {
5
- // The string cache no longer exists.
6
- }
7
-
8
- pub fn disable_string_cache() {
9
- // The string cache no longer exists.
10
- }
11
-
12
- pub fn using_string_cache() -> bool {
13
- // The string cache no longer exists.
14
- true
15
- }
16
-
17
- #[magnus::wrap(class = "Polars::RbStringCacheHolder")]
18
- pub struct RbStringCacheHolder {}
19
-
20
- impl RbStringCacheHolder {
21
- pub fn hold(ruby: &Ruby) -> RbResult<Value> {
22
- ruby.yield_splat(ruby.ary_new())
23
- }
24
- }