polars-df 0.15.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +274 -0
  3. data/Cargo.lock +1465 -867
  4. data/Cargo.toml +3 -0
  5. data/LICENSE.txt +2 -2
  6. data/README.md +87 -37
  7. data/ext/polars/Cargo.toml +47 -16
  8. data/ext/polars/src/c_api/allocator.rs +7 -0
  9. data/ext/polars/src/c_api/mod.rs +1 -0
  10. data/ext/polars/src/catalog/mod.rs +1 -0
  11. data/ext/polars/src/catalog/unity.rs +470 -0
  12. data/ext/polars/src/conversion/any_value.rs +99 -84
  13. data/ext/polars/src/conversion/categorical.rs +30 -0
  14. data/ext/polars/src/conversion/chunked_array.rs +71 -62
  15. data/ext/polars/src/conversion/datetime.rs +63 -0
  16. data/ext/polars/src/conversion/mod.rs +796 -312
  17. data/ext/polars/src/dataframe/construction.rs +6 -18
  18. data/ext/polars/src/dataframe/export.rs +30 -39
  19. data/ext/polars/src/dataframe/general.rs +294 -362
  20. data/ext/polars/src/dataframe/io.rs +33 -150
  21. data/ext/polars/src/dataframe/map.rs +175 -0
  22. data/ext/polars/src/dataframe/mod.rs +37 -5
  23. data/ext/polars/src/dataframe/serde.rs +23 -8
  24. data/ext/polars/src/error.rs +44 -7
  25. data/ext/polars/src/exceptions.rs +21 -8
  26. data/ext/polars/src/expr/array.rs +86 -22
  27. data/ext/polars/src/expr/binary.rs +50 -1
  28. data/ext/polars/src/expr/bitwise.rs +39 -0
  29. data/ext/polars/src/expr/categorical.rs +20 -0
  30. data/ext/polars/src/expr/datatype.rs +51 -0
  31. data/ext/polars/src/expr/datetime.rs +99 -41
  32. data/ext/polars/src/expr/extension.rs +12 -0
  33. data/ext/polars/src/expr/general.rs +252 -128
  34. data/ext/polars/src/expr/list.rs +56 -60
  35. data/ext/polars/src/expr/meta.rs +30 -35
  36. data/ext/polars/src/expr/mod.rs +28 -6
  37. data/ext/polars/src/expr/name.rs +29 -14
  38. data/ext/polars/src/expr/rolling.rs +111 -3
  39. data/ext/polars/src/expr/selector.rs +219 -0
  40. data/ext/polars/src/expr/serde.rs +28 -0
  41. data/ext/polars/src/expr/string.rs +118 -20
  42. data/ext/polars/src/expr/struct.rs +14 -1
  43. data/ext/polars/src/file.rs +194 -86
  44. data/ext/polars/src/functions/aggregation.rs +13 -12
  45. data/ext/polars/src/functions/business.rs +2 -3
  46. data/ext/polars/src/functions/eager.rs +3 -2
  47. data/ext/polars/src/functions/io.rs +90 -18
  48. data/ext/polars/src/functions/lazy.rs +267 -118
  49. data/ext/polars/src/functions/meta.rs +8 -7
  50. data/ext/polars/src/functions/misc.rs +1 -1
  51. data/ext/polars/src/functions/mod.rs +2 -1
  52. data/ext/polars/src/functions/range.rs +88 -31
  53. data/ext/polars/src/functions/strings.rs +6 -0
  54. data/ext/polars/src/functions/utils.rs +8 -0
  55. data/ext/polars/src/interop/arrow/mod.rs +52 -1
  56. data/ext/polars/src/interop/arrow/{to_ruby.rs → to_rb.rs} +37 -7
  57. data/ext/polars/src/interop/arrow/to_rust.rs +43 -0
  58. data/ext/polars/src/interop/numo/to_numo_df.rs +1 -1
  59. data/ext/polars/src/interop/numo/to_numo_series.rs +72 -50
  60. data/ext/polars/src/io/cloud_options.rs +107 -0
  61. data/ext/polars/src/io/mod.rs +4 -0
  62. data/ext/polars/src/io/scan_options.rs +113 -0
  63. data/ext/polars/src/io/sink_options.rs +46 -0
  64. data/ext/polars/src/io/sink_output.rs +21 -0
  65. data/ext/polars/src/lazyframe/exitable.rs +39 -0
  66. data/ext/polars/src/lazyframe/general.rs +846 -368
  67. data/ext/polars/src/lazyframe/mod.rs +58 -5
  68. data/ext/polars/src/lazyframe/optflags.rs +59 -0
  69. data/ext/polars/src/lazyframe/serde.rs +36 -4
  70. data/ext/polars/src/lazyframe/sink.rs +46 -0
  71. data/ext/polars/src/lazygroupby.rs +38 -9
  72. data/ext/polars/src/lib.rs +574 -165
  73. data/ext/polars/src/map/lazy.rs +44 -74
  74. data/ext/polars/src/map/mod.rs +18 -254
  75. data/ext/polars/src/map/series.rs +241 -1087
  76. data/ext/polars/src/on_startup.rs +192 -9
  77. data/ext/polars/src/prelude.rs +1 -0
  78. data/ext/polars/src/rb_modules.rs +10 -57
  79. data/ext/polars/src/ruby/exceptions.rs +26 -0
  80. data/ext/polars/src/ruby/gvl.rs +104 -0
  81. data/ext/polars/src/ruby/lazy.rs +46 -0
  82. data/ext/polars/src/ruby/mod.rs +11 -0
  83. data/ext/polars/src/ruby/numo.rs +52 -0
  84. data/ext/polars/src/ruby/plan_callback.rs +198 -0
  85. data/ext/polars/src/ruby/rb_modules.rs +16 -0
  86. data/ext/polars/src/ruby/ruby_convert_registry.rs +51 -0
  87. data/ext/polars/src/ruby/ruby_function.rs +11 -0
  88. data/ext/polars/src/ruby/ruby_udf.rs +164 -0
  89. data/ext/polars/src/ruby/thread.rs +65 -0
  90. data/ext/polars/src/ruby/utils.rs +39 -0
  91. data/ext/polars/src/series/aggregation.rs +116 -91
  92. data/ext/polars/src/series/arithmetic.rs +16 -22
  93. data/ext/polars/src/series/comparison.rs +101 -222
  94. data/ext/polars/src/series/construction.rs +80 -70
  95. data/ext/polars/src/series/export.rs +98 -56
  96. data/ext/polars/src/series/general.rs +323 -440
  97. data/ext/polars/src/series/import.rs +22 -5
  98. data/ext/polars/src/series/map.rs +103 -0
  99. data/ext/polars/src/series/mod.rs +57 -15
  100. data/ext/polars/src/series/scatter.rs +139 -82
  101. data/ext/polars/src/sql.rs +16 -9
  102. data/ext/polars/src/testing/frame.rs +31 -0
  103. data/ext/polars/src/testing/mod.rs +5 -0
  104. data/ext/polars/src/testing/series.rs +31 -0
  105. data/ext/polars/src/timeout.rs +105 -0
  106. data/ext/polars/src/utils.rs +105 -4
  107. data/lib/polars/array_expr.rb +500 -22
  108. data/lib/polars/array_name_space.rb +384 -10
  109. data/lib/polars/batched_csv_reader.rb +48 -66
  110. data/lib/polars/binary_expr.rb +217 -0
  111. data/lib/polars/binary_name_space.rb +155 -1
  112. data/lib/polars/cat_expr.rb +224 -0
  113. data/lib/polars/cat_name_space.rb +132 -32
  114. data/lib/polars/catalog/unity/catalog_info.rb +20 -0
  115. data/lib/polars/catalog/unity/column_info.rb +31 -0
  116. data/lib/polars/catalog/unity/namespace_info.rb +21 -0
  117. data/lib/polars/catalog/unity/table_info.rb +50 -0
  118. data/lib/polars/catalog.rb +448 -0
  119. data/lib/polars/collect_batches.rb +22 -0
  120. data/lib/polars/config.rb +3 -3
  121. data/lib/polars/convert.rb +201 -36
  122. data/lib/polars/data_frame.rb +2851 -1017
  123. data/lib/polars/data_frame_plot.rb +173 -0
  124. data/lib/polars/data_type_expr.rb +52 -0
  125. data/lib/polars/data_type_group.rb +6 -0
  126. data/lib/polars/data_types.rb +118 -18
  127. data/lib/polars/date_time_expr.rb +426 -84
  128. data/lib/polars/date_time_name_space.rb +384 -111
  129. data/lib/polars/dynamic_group_by.rb +102 -10
  130. data/lib/polars/exceptions.rb +50 -5
  131. data/lib/polars/expr.rb +2159 -915
  132. data/lib/polars/extension_expr.rb +39 -0
  133. data/lib/polars/extension_name_space.rb +39 -0
  134. data/lib/polars/functions/aggregation/horizontal.rb +11 -6
  135. data/lib/polars/functions/aggregation/vertical.rb +2 -3
  136. data/lib/polars/functions/as_datatype.rb +290 -8
  137. data/lib/polars/functions/business.rb +95 -0
  138. data/lib/polars/functions/col.rb +6 -5
  139. data/lib/polars/functions/datatype.rb +62 -0
  140. data/lib/polars/functions/eager.rb +426 -24
  141. data/lib/polars/functions/escape_regex.rb +21 -0
  142. data/lib/polars/functions/lazy.rb +813 -195
  143. data/lib/polars/functions/lit.rb +21 -10
  144. data/lib/polars/functions/range/int_range.rb +74 -2
  145. data/lib/polars/functions/range/linear_space.rb +195 -0
  146. data/lib/polars/functions/range/time_range.rb +1 -1
  147. data/lib/polars/functions/repeat.rb +7 -12
  148. data/lib/polars/functions/whenthen.rb +2 -2
  149. data/lib/polars/group_by.rb +188 -58
  150. data/lib/polars/iceberg_dataset.rb +108 -0
  151. data/lib/polars/in_process_query.rb +37 -0
  152. data/lib/polars/io/cloud.rb +18 -0
  153. data/lib/polars/io/csv.rb +336 -128
  154. data/lib/polars/io/database.rb +19 -4
  155. data/lib/polars/io/delta.rb +134 -0
  156. data/lib/polars/io/iceberg.rb +34 -0
  157. data/lib/polars/io/ipc.rb +63 -63
  158. data/lib/polars/io/json.rb +16 -0
  159. data/lib/polars/io/lines.rb +172 -0
  160. data/lib/polars/io/ndjson.rb +176 -20
  161. data/lib/polars/io/parquet.rb +173 -95
  162. data/lib/polars/io/scan_options.rb +55 -0
  163. data/lib/polars/io/sink_options.rb +27 -0
  164. data/lib/polars/io/utils.rb +17 -0
  165. data/lib/polars/lazy_frame.rb +3017 -622
  166. data/lib/polars/lazy_group_by.rb +436 -2
  167. data/lib/polars/list_expr.rb +551 -59
  168. data/lib/polars/list_name_space.rb +465 -51
  169. data/lib/polars/meta_expr.rb +146 -24
  170. data/lib/polars/name_expr.rb +87 -2
  171. data/lib/polars/query_opt_flags.rb +264 -0
  172. data/lib/polars/rolling_group_by.rb +90 -5
  173. data/lib/polars/scan_cast_options.rb +86 -0
  174. data/lib/polars/schema.rb +128 -0
  175. data/lib/polars/selector.rb +245 -0
  176. data/lib/polars/selectors.rb +1048 -201
  177. data/lib/polars/series.rb +2522 -774
  178. data/lib/polars/series_plot.rb +72 -0
  179. data/lib/polars/slice.rb +1 -1
  180. data/lib/polars/sql_context.rb +13 -6
  181. data/lib/polars/string_cache.rb +19 -72
  182. data/lib/polars/string_expr.rb +561 -107
  183. data/lib/polars/string_name_space.rb +781 -109
  184. data/lib/polars/struct_expr.rb +139 -18
  185. data/lib/polars/struct_name_space.rb +19 -1
  186. data/lib/polars/testing.rb +24 -273
  187. data/lib/polars/utils/constants.rb +2 -0
  188. data/lib/polars/utils/construction/data_frame.rb +410 -0
  189. data/lib/polars/utils/construction/series.rb +350 -0
  190. data/lib/polars/utils/construction/utils.rb +9 -0
  191. data/lib/polars/utils/convert.rb +18 -8
  192. data/lib/polars/utils/deprecation.rb +11 -0
  193. data/lib/polars/utils/parse.rb +62 -9
  194. data/lib/polars/utils/reduce_balanced.rb +43 -0
  195. data/lib/polars/utils/serde.rb +22 -0
  196. data/lib/polars/utils/unstable.rb +19 -0
  197. data/lib/polars/utils/various.rb +86 -1
  198. data/lib/polars/utils.rb +63 -48
  199. data/lib/polars/version.rb +1 -1
  200. data/lib/polars.rb +85 -2
  201. metadata +80 -28
  202. data/ext/polars/src/allocator.rs +0 -13
  203. data/ext/polars/src/batched_csv.rs +0 -138
  204. data/ext/polars/src/functions/string_cache.rs +0 -25
  205. data/ext/polars/src/map/dataframe.rs +0 -338
  206. data/lib/polars/plot.rb +0 -109
@@ -4,17 +4,19 @@ module Polars
4
4
  # This has an `.agg` method which allows you to run all polars expressions in a
5
5
  # group by context.
6
6
  class DynamicGroupBy
7
+ # @private
7
8
  def initialize(
8
9
  df,
9
10
  index_column,
10
11
  every,
11
12
  period,
12
13
  offset,
13
- truncate,
14
14
  include_boundaries,
15
15
  closed,
16
- by,
17
- start_by
16
+ label,
17
+ group_by,
18
+ start_by,
19
+ predicates
18
20
  )
19
21
  period = Utils.parse_as_duration_string(period)
20
22
  offset = Utils.parse_as_duration_string(offset)
@@ -25,28 +27,118 @@ module Polars
25
27
  @every = every
26
28
  @period = period
27
29
  @offset = offset
28
- @truncate = truncate
29
30
  @include_boundaries = include_boundaries
30
31
  @closed = closed
31
- @by = by
32
+ @label = label
33
+ @group_by = group_by
32
34
  @start_by = start_by
35
+ @predicates = predicates
33
36
  end
34
37
 
38
+ # Filter groups with a list of predicates after aggregation.
39
+ #
40
+ # Using this method is equivalent to adding the predicates to the aggregation and
41
+ # filtering afterwards.
42
+ #
43
+ # This method can be chained and all conditions will be combined using `&`.
44
+ #
45
+ # @param predicates [Array]
46
+ # Expressions that evaluate to a boolean value for each group. Typically, this
47
+ # requires the use of an aggregation function. Multiple predicates are
48
+ # combined using `&`.
49
+ #
50
+ # @return [DynamicGroupBy]
51
+ def having(*predicates)
52
+ DynamicGroupBy.new(
53
+ @df,
54
+ @time_column,
55
+ @every,
56
+ @period,
57
+ @offset,
58
+ @include_boundaries,
59
+ @closed,
60
+ @label,
61
+ @group_by,
62
+ @start_by,
63
+ Utils._chain_predicates(@predicates, predicates)
64
+ )
65
+ end
66
+
67
+ # Compute aggregations for each group of a group by operation.
68
+ #
69
+ # @param aggs [Array]
70
+ # Aggregations to compute for each group of the group by operation,
71
+ # specified as positional arguments.
72
+ # Accepts expression input. Strings are parsed as column names.
73
+ # @param named_aggs [Hash]
74
+ # Additional aggregations, specified as keyword arguments.
75
+ # The resulting columns will be renamed to the keyword used.
76
+ #
77
+ # @return [DataFrame]
35
78
  def agg(*aggs, **named_aggs)
79
+ group_by =
80
+ @df.lazy.group_by_dynamic(
81
+ @time_column,
82
+ every: @every,
83
+ period: @period,
84
+ offset: @offset,
85
+ include_boundaries: @include_boundaries,
86
+ closed: @closed,
87
+ label: @label,
88
+ group_by: @group_by,
89
+ start_by: @start_by
90
+ )
91
+
92
+ if @predicates&.any?
93
+ group_by = group_by.having(@predicates)
94
+ end
95
+
96
+ group_by.agg(*aggs, **named_aggs).collect(
97
+ optimizations: QueryOptFlags.none
98
+ )
99
+ end
100
+
101
+ # Apply a custom/user-defined function (UDF) over the groups as a new DataFrame.
102
+ #
103
+ # Using this is considered an anti-pattern as it will be very slow because:
104
+ #
105
+ # - it forces the engine to materialize the whole `DataFrames` for the groups.
106
+ # - it is not parallelized.
107
+ # - it blocks optimizations as the passed python function is opaque to the
108
+ # optimizer.
109
+ #
110
+ # The idiomatic way to apply custom functions over multiple columns is using:
111
+ #
112
+ # `Polars.struct([my_columns]).map_elements { |struct_series| ... }`
113
+ #
114
+ # @param schema [Object]
115
+ # Schema of the output function. This has to be known statically. If the
116
+ # given schema is incorrect, this is a bug in the caller's query and may
117
+ # lead to errors. If set to None, polars assumes the schema is unchanged.
118
+ #
119
+ # @return [DataFrame]
120
+ def map_groups(
121
+ schema,
122
+ &function
123
+ )
124
+ if @predicates&.any?
125
+ msg = "cannot call `map_groups` when filtering groups with `having`"
126
+ raise TypeError, msg
127
+ end
128
+
36
129
  @df.lazy
37
130
  .group_by_dynamic(
38
- @time_column,
131
+ index_column: @time_column,
39
132
  every: @every,
40
133
  period: @period,
41
134
  offset: @offset,
42
- truncate: @truncate,
43
135
  include_boundaries: @include_boundaries,
44
136
  closed: @closed,
45
- by: @by,
137
+ group_by: @group_by,
46
138
  start_by: @start_by
47
139
  )
48
- .agg(*aggs, **named_aggs)
49
- .collect(no_optimization: true, string_cache: false)
140
+ .map_groups(schema, &function)
141
+ .collect(optimizations: QueryOptFlags.none)
50
142
  end
51
143
  end
52
144
  end
@@ -3,13 +3,61 @@ module Polars
3
3
  # Base class for all Polars errors.
4
4
  class Error < StandardError; end
5
5
 
6
+ # @private
7
+ # Exception raised when a specified column is not found.
8
+ class ColumnNotFoundError < Error; end
9
+
10
+ # @private
11
+ # Exception raised when Polars could not perform an underlying computation.
12
+ class ComputeError < Error; end
13
+
14
+ # @private
15
+ # Exception raised when a column name is duplicated.
16
+ class DuplicateError < Error; end
17
+
6
18
  # @private
7
19
  # Exception raised when an operation is not allowed (or possible) against a given object or data structure.
8
20
  class InvalidOperationError < Error; end
9
21
 
10
22
  # @private
11
- # Exception raised when an unsupported testing assert is made.
12
- class InvalidAssert < Error; end
23
+ # Exception raised when an operation cannot be performed on an empty data structure.
24
+ class NoDataError < Error; end
25
+
26
+ # @private
27
+ # Exception raised when the given index is out of bounds.
28
+ class OutOfBoundsError < Error; end
29
+
30
+ # @private
31
+ # Exception raised when an unexpected state causes a panic in the underlying Rust library.
32
+ class PanicException < Error; end
33
+
34
+ # @private
35
+ # Exception raised when an unexpected schema mismatch causes an error.
36
+ class SchemaError < Error; end
37
+
38
+ # @private
39
+ # Exception raised when a specified schema field is not found.
40
+ class SchemaFieldNotFoundError < Error; end
41
+
42
+ # @private
43
+ # Exception raised when trying to perform operations on data structures with incompatible shapes.
44
+ class ShapeError < Error; end
45
+
46
+ # @private
47
+ # Exception raised when an error occurs in the SQL interface.
48
+ class SQLInterfaceError < Error; end
49
+
50
+ # @private
51
+ # Exception raised from the SQL interface when encountering invalid syntax.
52
+ class SQLSyntaxError < Error; end
53
+
54
+ # @private
55
+ # Exception raised when string caches come from different sources.
56
+ class StringCacheMismatchError < Error; end
57
+
58
+ # @private
59
+ # Exception raised when a specified Struct field is not found.
60
+ class StructFieldNotFoundError < Error; end
13
61
 
14
62
  # @private
15
63
  # Exception raised when the number of returned rows does not match expectation.
@@ -26,9 +74,6 @@ module Polars
26
74
  # @private
27
75
  class AssertionError < Error; end
28
76
 
29
- # @private
30
- class ComputeError < Error; end
31
-
32
77
  # @private
33
78
  class Todo < Error
34
79
  def message