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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +274 -0
- data/Cargo.lock +1465 -867
- data/Cargo.toml +3 -0
- data/LICENSE.txt +2 -2
- data/README.md +87 -37
- data/ext/polars/Cargo.toml +47 -16
- data/ext/polars/src/c_api/allocator.rs +7 -0
- data/ext/polars/src/c_api/mod.rs +1 -0
- data/ext/polars/src/catalog/mod.rs +1 -0
- data/ext/polars/src/catalog/unity.rs +470 -0
- data/ext/polars/src/conversion/any_value.rs +99 -84
- data/ext/polars/src/conversion/categorical.rs +30 -0
- data/ext/polars/src/conversion/chunked_array.rs +71 -62
- data/ext/polars/src/conversion/datetime.rs +63 -0
- data/ext/polars/src/conversion/mod.rs +796 -312
- data/ext/polars/src/dataframe/construction.rs +6 -18
- data/ext/polars/src/dataframe/export.rs +30 -39
- data/ext/polars/src/dataframe/general.rs +294 -362
- data/ext/polars/src/dataframe/io.rs +33 -150
- data/ext/polars/src/dataframe/map.rs +175 -0
- data/ext/polars/src/dataframe/mod.rs +37 -5
- data/ext/polars/src/dataframe/serde.rs +23 -8
- data/ext/polars/src/error.rs +44 -7
- data/ext/polars/src/exceptions.rs +21 -8
- data/ext/polars/src/expr/array.rs +86 -22
- data/ext/polars/src/expr/binary.rs +50 -1
- data/ext/polars/src/expr/bitwise.rs +39 -0
- data/ext/polars/src/expr/categorical.rs +20 -0
- data/ext/polars/src/expr/datatype.rs +51 -0
- data/ext/polars/src/expr/datetime.rs +99 -41
- data/ext/polars/src/expr/extension.rs +12 -0
- data/ext/polars/src/expr/general.rs +252 -128
- data/ext/polars/src/expr/list.rs +56 -60
- data/ext/polars/src/expr/meta.rs +30 -35
- data/ext/polars/src/expr/mod.rs +28 -6
- data/ext/polars/src/expr/name.rs +29 -14
- data/ext/polars/src/expr/rolling.rs +111 -3
- data/ext/polars/src/expr/selector.rs +219 -0
- data/ext/polars/src/expr/serde.rs +28 -0
- data/ext/polars/src/expr/string.rs +118 -20
- data/ext/polars/src/expr/struct.rs +14 -1
- data/ext/polars/src/file.rs +194 -86
- data/ext/polars/src/functions/aggregation.rs +13 -12
- data/ext/polars/src/functions/business.rs +2 -3
- data/ext/polars/src/functions/eager.rs +3 -2
- data/ext/polars/src/functions/io.rs +90 -18
- data/ext/polars/src/functions/lazy.rs +267 -118
- data/ext/polars/src/functions/meta.rs +8 -7
- data/ext/polars/src/functions/misc.rs +1 -1
- data/ext/polars/src/functions/mod.rs +2 -1
- data/ext/polars/src/functions/range.rs +88 -31
- data/ext/polars/src/functions/strings.rs +6 -0
- data/ext/polars/src/functions/utils.rs +8 -0
- data/ext/polars/src/interop/arrow/mod.rs +52 -1
- data/ext/polars/src/interop/arrow/{to_ruby.rs → to_rb.rs} +37 -7
- data/ext/polars/src/interop/arrow/to_rust.rs +43 -0
- data/ext/polars/src/interop/numo/to_numo_df.rs +1 -1
- data/ext/polars/src/interop/numo/to_numo_series.rs +72 -50
- data/ext/polars/src/io/cloud_options.rs +107 -0
- data/ext/polars/src/io/mod.rs +4 -0
- data/ext/polars/src/io/scan_options.rs +113 -0
- data/ext/polars/src/io/sink_options.rs +46 -0
- data/ext/polars/src/io/sink_output.rs +21 -0
- data/ext/polars/src/lazyframe/exitable.rs +39 -0
- data/ext/polars/src/lazyframe/general.rs +846 -368
- data/ext/polars/src/lazyframe/mod.rs +58 -5
- data/ext/polars/src/lazyframe/optflags.rs +59 -0
- data/ext/polars/src/lazyframe/serde.rs +36 -4
- data/ext/polars/src/lazyframe/sink.rs +46 -0
- data/ext/polars/src/lazygroupby.rs +38 -9
- data/ext/polars/src/lib.rs +574 -165
- data/ext/polars/src/map/lazy.rs +44 -74
- data/ext/polars/src/map/mod.rs +18 -254
- data/ext/polars/src/map/series.rs +241 -1087
- data/ext/polars/src/on_startup.rs +192 -9
- data/ext/polars/src/prelude.rs +1 -0
- data/ext/polars/src/rb_modules.rs +10 -57
- data/ext/polars/src/ruby/exceptions.rs +26 -0
- data/ext/polars/src/ruby/gvl.rs +104 -0
- data/ext/polars/src/ruby/lazy.rs +46 -0
- data/ext/polars/src/ruby/mod.rs +11 -0
- data/ext/polars/src/ruby/numo.rs +52 -0
- data/ext/polars/src/ruby/plan_callback.rs +198 -0
- data/ext/polars/src/ruby/rb_modules.rs +16 -0
- data/ext/polars/src/ruby/ruby_convert_registry.rs +51 -0
- data/ext/polars/src/ruby/ruby_function.rs +11 -0
- data/ext/polars/src/ruby/ruby_udf.rs +164 -0
- data/ext/polars/src/ruby/thread.rs +65 -0
- data/ext/polars/src/ruby/utils.rs +39 -0
- data/ext/polars/src/series/aggregation.rs +116 -91
- data/ext/polars/src/series/arithmetic.rs +16 -22
- data/ext/polars/src/series/comparison.rs +101 -222
- data/ext/polars/src/series/construction.rs +80 -70
- data/ext/polars/src/series/export.rs +98 -56
- data/ext/polars/src/series/general.rs +323 -440
- data/ext/polars/src/series/import.rs +22 -5
- data/ext/polars/src/series/map.rs +103 -0
- data/ext/polars/src/series/mod.rs +57 -15
- data/ext/polars/src/series/scatter.rs +139 -82
- data/ext/polars/src/sql.rs +16 -9
- data/ext/polars/src/testing/frame.rs +31 -0
- data/ext/polars/src/testing/mod.rs +5 -0
- data/ext/polars/src/testing/series.rs +31 -0
- data/ext/polars/src/timeout.rs +105 -0
- data/ext/polars/src/utils.rs +105 -4
- data/lib/polars/array_expr.rb +500 -22
- data/lib/polars/array_name_space.rb +384 -10
- data/lib/polars/batched_csv_reader.rb +48 -66
- data/lib/polars/binary_expr.rb +217 -0
- data/lib/polars/binary_name_space.rb +155 -1
- data/lib/polars/cat_expr.rb +224 -0
- data/lib/polars/cat_name_space.rb +132 -32
- data/lib/polars/catalog/unity/catalog_info.rb +20 -0
- data/lib/polars/catalog/unity/column_info.rb +31 -0
- data/lib/polars/catalog/unity/namespace_info.rb +21 -0
- data/lib/polars/catalog/unity/table_info.rb +50 -0
- data/lib/polars/catalog.rb +448 -0
- data/lib/polars/collect_batches.rb +22 -0
- data/lib/polars/config.rb +3 -3
- data/lib/polars/convert.rb +201 -36
- data/lib/polars/data_frame.rb +2851 -1017
- data/lib/polars/data_frame_plot.rb +173 -0
- data/lib/polars/data_type_expr.rb +52 -0
- data/lib/polars/data_type_group.rb +6 -0
- data/lib/polars/data_types.rb +118 -18
- data/lib/polars/date_time_expr.rb +426 -84
- data/lib/polars/date_time_name_space.rb +384 -111
- data/lib/polars/dynamic_group_by.rb +102 -10
- data/lib/polars/exceptions.rb +50 -5
- data/lib/polars/expr.rb +2159 -915
- data/lib/polars/extension_expr.rb +39 -0
- data/lib/polars/extension_name_space.rb +39 -0
- data/lib/polars/functions/aggregation/horizontal.rb +11 -6
- data/lib/polars/functions/aggregation/vertical.rb +2 -3
- data/lib/polars/functions/as_datatype.rb +290 -8
- data/lib/polars/functions/business.rb +95 -0
- data/lib/polars/functions/col.rb +6 -5
- data/lib/polars/functions/datatype.rb +62 -0
- data/lib/polars/functions/eager.rb +426 -24
- data/lib/polars/functions/escape_regex.rb +21 -0
- data/lib/polars/functions/lazy.rb +813 -195
- data/lib/polars/functions/lit.rb +21 -10
- data/lib/polars/functions/range/int_range.rb +74 -2
- data/lib/polars/functions/range/linear_space.rb +195 -0
- data/lib/polars/functions/range/time_range.rb +1 -1
- data/lib/polars/functions/repeat.rb +7 -12
- data/lib/polars/functions/whenthen.rb +2 -2
- data/lib/polars/group_by.rb +188 -58
- data/lib/polars/iceberg_dataset.rb +108 -0
- data/lib/polars/in_process_query.rb +37 -0
- data/lib/polars/io/cloud.rb +18 -0
- data/lib/polars/io/csv.rb +336 -128
- data/lib/polars/io/database.rb +19 -4
- data/lib/polars/io/delta.rb +134 -0
- data/lib/polars/io/iceberg.rb +34 -0
- data/lib/polars/io/ipc.rb +63 -63
- data/lib/polars/io/json.rb +16 -0
- data/lib/polars/io/lines.rb +172 -0
- data/lib/polars/io/ndjson.rb +176 -20
- data/lib/polars/io/parquet.rb +173 -95
- data/lib/polars/io/scan_options.rb +55 -0
- data/lib/polars/io/sink_options.rb +27 -0
- data/lib/polars/io/utils.rb +17 -0
- data/lib/polars/lazy_frame.rb +3017 -622
- data/lib/polars/lazy_group_by.rb +436 -2
- data/lib/polars/list_expr.rb +551 -59
- data/lib/polars/list_name_space.rb +465 -51
- data/lib/polars/meta_expr.rb +146 -24
- data/lib/polars/name_expr.rb +87 -2
- data/lib/polars/query_opt_flags.rb +264 -0
- data/lib/polars/rolling_group_by.rb +90 -5
- data/lib/polars/scan_cast_options.rb +86 -0
- data/lib/polars/schema.rb +128 -0
- data/lib/polars/selector.rb +245 -0
- data/lib/polars/selectors.rb +1048 -201
- data/lib/polars/series.rb +2522 -774
- data/lib/polars/series_plot.rb +72 -0
- data/lib/polars/slice.rb +1 -1
- data/lib/polars/sql_context.rb +13 -6
- data/lib/polars/string_cache.rb +19 -72
- data/lib/polars/string_expr.rb +561 -107
- data/lib/polars/string_name_space.rb +781 -109
- data/lib/polars/struct_expr.rb +139 -18
- data/lib/polars/struct_name_space.rb +19 -1
- data/lib/polars/testing.rb +24 -273
- data/lib/polars/utils/constants.rb +2 -0
- data/lib/polars/utils/construction/data_frame.rb +410 -0
- data/lib/polars/utils/construction/series.rb +350 -0
- data/lib/polars/utils/construction/utils.rb +9 -0
- data/lib/polars/utils/convert.rb +18 -8
- data/lib/polars/utils/deprecation.rb +11 -0
- data/lib/polars/utils/parse.rb +62 -9
- data/lib/polars/utils/reduce_balanced.rb +43 -0
- data/lib/polars/utils/serde.rb +22 -0
- data/lib/polars/utils/unstable.rb +19 -0
- data/lib/polars/utils/various.rb +86 -1
- data/lib/polars/utils.rb +63 -48
- data/lib/polars/version.rb +1 -1
- data/lib/polars.rb +85 -2
- metadata +80 -28
- data/ext/polars/src/allocator.rs +0 -13
- data/ext/polars/src/batched_csv.rs +0 -138
- data/ext/polars/src/functions/string_cache.rs +0 -25
- data/ext/polars/src/map/dataframe.rs +0 -338
- data/lib/polars/plot.rb +0 -109
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module Polars
|
|
2
|
+
# Options for scanning files.
|
|
3
|
+
class ScanCastOptions
|
|
4
|
+
attr_reader :integer_cast, :float_cast, :datetime_cast, :missing_struct_fields, :extra_struct_fields, :categorical_to_string
|
|
5
|
+
|
|
6
|
+
# Common configuration for scanning files.
|
|
7
|
+
#
|
|
8
|
+
# @note
|
|
9
|
+
# This functionality is considered **unstable**. It may be changed
|
|
10
|
+
# at any point without it being considered a breaking change.
|
|
11
|
+
#
|
|
12
|
+
# @param integer_cast ['upcast', 'forbid']
|
|
13
|
+
# Configuration for casting from integer types:
|
|
14
|
+
#
|
|
15
|
+
# * `upcast`: Allow lossless casting to wider integer types.
|
|
16
|
+
# * `forbid`: Raises an error if dtypes do not match.
|
|
17
|
+
#
|
|
18
|
+
# @param float_cast ['upcast', 'downcast', 'forbid']
|
|
19
|
+
# Configuration for casting from float types:
|
|
20
|
+
#
|
|
21
|
+
# * `upcast`: Allow casting to higher precision float types.
|
|
22
|
+
# * `downcast`: Allow casting to lower precision float types.
|
|
23
|
+
# * `forbid`: Raises an error if dtypes do not match.
|
|
24
|
+
#
|
|
25
|
+
# @param datetime_cast ['nanosecond-downcast', 'convert-timezone', 'forbid']
|
|
26
|
+
# Configuration for casting from datetime types:
|
|
27
|
+
#
|
|
28
|
+
# * `nanosecond-downcast`: Allow nanosecond precision datetime to be
|
|
29
|
+
# downcasted to any lower precision. This has a similar effect to
|
|
30
|
+
# PyArrow's `coerce_int96_timestamp_unit`.
|
|
31
|
+
# * `convert-timezone`: Allow casting to a different timezone.
|
|
32
|
+
# * `forbid`: Raises an error if dtypes do not match.
|
|
33
|
+
#
|
|
34
|
+
# @param missing_struct_fields ['insert', 'raise']
|
|
35
|
+
# Configuration for behavior when struct fields defined in the schema
|
|
36
|
+
# are missing from the data:
|
|
37
|
+
#
|
|
38
|
+
# * `insert`: Inserts the missing fields.
|
|
39
|
+
# * `raise`: Raises an error.
|
|
40
|
+
#
|
|
41
|
+
# @param extra_struct_fields ['ignore', 'raise']
|
|
42
|
+
# Configuration for behavior when extra struct fields outside of the
|
|
43
|
+
# defined schema are encountered in the data:
|
|
44
|
+
#
|
|
45
|
+
# * `ignore`: Silently ignores.
|
|
46
|
+
# * `raise`: Raises an error.
|
|
47
|
+
def initialize(
|
|
48
|
+
integer_cast: "forbid",
|
|
49
|
+
float_cast: "forbid",
|
|
50
|
+
datetime_cast: "forbid",
|
|
51
|
+
missing_struct_fields: "raise",
|
|
52
|
+
extra_struct_fields: "raise",
|
|
53
|
+
categorical_to_string: "forbid",
|
|
54
|
+
_internal_call: false
|
|
55
|
+
)
|
|
56
|
+
if !_internal_call
|
|
57
|
+
warn "ScanCastOptions is considered unstable."
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
@integer_cast = integer_cast
|
|
61
|
+
@float_cast = float_cast
|
|
62
|
+
@datetime_cast = datetime_cast
|
|
63
|
+
@missing_struct_fields = missing_struct_fields
|
|
64
|
+
@extra_struct_fields = extra_struct_fields
|
|
65
|
+
@categorical_to_string = categorical_to_string
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self._default
|
|
69
|
+
new(_internal_call: true)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def self._default_iceberg
|
|
73
|
+
@_default_cast_options_iceberg ||= begin
|
|
74
|
+
ScanCastOptions.new(
|
|
75
|
+
integer_cast: "upcast",
|
|
76
|
+
float_cast: ["upcast", "downcast"],
|
|
77
|
+
datetime_cast: ["nanosecond-downcast", "convert-timezone"],
|
|
78
|
+
missing_struct_fields: "insert",
|
|
79
|
+
extra_struct_fields: "ignore",
|
|
80
|
+
categorical_to_string: "allow",
|
|
81
|
+
_internal_call: true
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
module Polars
|
|
2
|
+
class Schema
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
# Ordered mapping of column names to their data type.
|
|
6
|
+
#
|
|
7
|
+
# @param schema [Object]
|
|
8
|
+
# The schema definition given by column names and their associated
|
|
9
|
+
# Polars data type. Accepts a mapping or an enumerable of arrays.
|
|
10
|
+
def initialize(schema = nil, check_dtypes: true)
|
|
11
|
+
@schema = {}
|
|
12
|
+
|
|
13
|
+
if schema.respond_to?(:arrow_c_schema) && !schema.is_a?(Schema)
|
|
14
|
+
Plr.init_polars_schema_from_arrow_c_schema(@schema, schema)
|
|
15
|
+
return
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
input = schema || {}
|
|
19
|
+
input.each do |name, tp|
|
|
20
|
+
if !check_dtypes
|
|
21
|
+
@schema[name] = tp
|
|
22
|
+
elsif Utils.is_polars_dtype(tp)
|
|
23
|
+
@schema[name] = _check_dtype(tp)
|
|
24
|
+
else
|
|
25
|
+
self[name] = tp
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns the data type of the column.
|
|
31
|
+
#
|
|
32
|
+
# @return [Object]
|
|
33
|
+
def [](key)
|
|
34
|
+
@schema[key]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Sets the data type of the column.
|
|
38
|
+
#
|
|
39
|
+
# @return [Object]
|
|
40
|
+
def []=(name, dtype)
|
|
41
|
+
_check_dtype(dtype)
|
|
42
|
+
@schema[name] = dtype
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @private
|
|
46
|
+
def arrow_c_schema
|
|
47
|
+
Plr.polars_schema_to_rbcapsule(self)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Get the column names of the schema.
|
|
51
|
+
#
|
|
52
|
+
# @return [Array]
|
|
53
|
+
#
|
|
54
|
+
# @example
|
|
55
|
+
# s = Polars::Schema.new({"x" => Polars::Float64.new, "y" => Polars::Datetime.new(time_zone: "UTC")})
|
|
56
|
+
# s.names
|
|
57
|
+
# # => ["x", "y"]
|
|
58
|
+
def names
|
|
59
|
+
@schema.keys
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Get the data types of the schema.
|
|
63
|
+
#
|
|
64
|
+
# @return [Array]
|
|
65
|
+
#
|
|
66
|
+
# @example
|
|
67
|
+
# s = Polars::Schema.new({"x" => Polars::UInt8.new, "y" => Polars::List.new(Polars::UInt8)})
|
|
68
|
+
# s.dtypes
|
|
69
|
+
# # => [Polars::UInt8, Polars::List(Polars::UInt8)]
|
|
70
|
+
def dtypes
|
|
71
|
+
@schema.values
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Get the number of schema entries.
|
|
75
|
+
#
|
|
76
|
+
# @return [Integer]
|
|
77
|
+
#
|
|
78
|
+
# @example
|
|
79
|
+
# s = Polars::Schema.new({"x" => Polars::Int32.new, "y" => Polars::List.new(Polars::String)})
|
|
80
|
+
# s.length
|
|
81
|
+
# # => 2
|
|
82
|
+
def length
|
|
83
|
+
@schema.length
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Returns a string representing the Schema.
|
|
87
|
+
#
|
|
88
|
+
# @return [String]
|
|
89
|
+
def to_s
|
|
90
|
+
"#{self.class.name}(#{@schema})"
|
|
91
|
+
end
|
|
92
|
+
alias_method :inspect, :to_s
|
|
93
|
+
|
|
94
|
+
# @private
|
|
95
|
+
def each(&block)
|
|
96
|
+
@schema.each(&block)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @private
|
|
100
|
+
def include?(name)
|
|
101
|
+
@schema.include?(name)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @private
|
|
105
|
+
def to_h(&block)
|
|
106
|
+
@schema.to_h(&block)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
def _check_dtype(tp)
|
|
112
|
+
if !tp.is_a?(DataType)
|
|
113
|
+
# note: if nested/decimal, or has signature params, this implies required args
|
|
114
|
+
if tp.nested? || tp.decimal? || _required_init_args(tp)
|
|
115
|
+
msg = "dtypes must be fully-specified, got: #{tp.inspect}"
|
|
116
|
+
raise TypeError, msg
|
|
117
|
+
end
|
|
118
|
+
tp = tp.new
|
|
119
|
+
end
|
|
120
|
+
tp
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def _required_init_args(tp)
|
|
124
|
+
arity = tp.method(:new).arity
|
|
125
|
+
arity > 0 || arity < -1
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
module Polars
|
|
2
|
+
# Base column selector expression/proxy.
|
|
3
|
+
class Selector < Expr
|
|
4
|
+
# @private
|
|
5
|
+
attr_accessor :_rbselector
|
|
6
|
+
|
|
7
|
+
# @private
|
|
8
|
+
def self._from_rbselector(rbselector)
|
|
9
|
+
slf = new
|
|
10
|
+
slf._rbselector = rbselector
|
|
11
|
+
slf._rbexpr = RbExpr.new_selector(rbselector)
|
|
12
|
+
slf
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Returns a string representing the Selector.
|
|
16
|
+
#
|
|
17
|
+
# @return [String]
|
|
18
|
+
def inspect
|
|
19
|
+
Expr._from_rbexpr(_rbexpr).to_s
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @private
|
|
23
|
+
def self._by_dtype(dtypes)
|
|
24
|
+
selectors = []
|
|
25
|
+
concrete_dtypes = []
|
|
26
|
+
dtypes.each do |dt|
|
|
27
|
+
if Utils.is_polars_dtype(dt)
|
|
28
|
+
concrete_dtypes += [dt]
|
|
29
|
+
else
|
|
30
|
+
raise Todo
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
dtype_selector = _from_rbselector(RbSelector.by_dtype(concrete_dtypes))
|
|
35
|
+
|
|
36
|
+
if selectors.length == 0
|
|
37
|
+
return dtype_selector
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
selector = selectors[0]
|
|
41
|
+
selectors[1..].each do |s|
|
|
42
|
+
selector = selector | s
|
|
43
|
+
end
|
|
44
|
+
if concrete_dtypes.length == 0
|
|
45
|
+
selector
|
|
46
|
+
else
|
|
47
|
+
dtype_selector | selector
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @private
|
|
52
|
+
def self._by_name(names, strict:, expand_patterns:)
|
|
53
|
+
_from_rbselector(RbSelector.by_name(names, strict, expand_patterns))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Invert the selector.
|
|
57
|
+
#
|
|
58
|
+
# @return [Selector]
|
|
59
|
+
def ~
|
|
60
|
+
Selectors.all - self
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# AND.
|
|
64
|
+
#
|
|
65
|
+
# @return [Selector]
|
|
66
|
+
def &(other)
|
|
67
|
+
if Utils.is_column(other)
|
|
68
|
+
colname = other.meta.output_name
|
|
69
|
+
other = by_name(colname)
|
|
70
|
+
end
|
|
71
|
+
if Utils.is_selector(other)
|
|
72
|
+
Selector._from_rbselector(
|
|
73
|
+
_rbselector.intersect(other._rbselector)
|
|
74
|
+
)
|
|
75
|
+
else
|
|
76
|
+
as_expr & other
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# OR.
|
|
81
|
+
#
|
|
82
|
+
# @return [Selector]
|
|
83
|
+
def |(other)
|
|
84
|
+
if Utils.is_column(other)
|
|
85
|
+
other = by_name(other.meta.output_name)
|
|
86
|
+
end
|
|
87
|
+
if Utils.is_selector(other)
|
|
88
|
+
Selector._from_rbselector(
|
|
89
|
+
_rbselector.union(other._rbselector)
|
|
90
|
+
)
|
|
91
|
+
else
|
|
92
|
+
as_expr | other
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Difference.
|
|
97
|
+
#
|
|
98
|
+
# @return [Selector]
|
|
99
|
+
def -(other)
|
|
100
|
+
if Utils.is_selector(other)
|
|
101
|
+
Selector._from_rbselector(
|
|
102
|
+
_rbselector.difference(other._rbselector)
|
|
103
|
+
)
|
|
104
|
+
else
|
|
105
|
+
as_expr - other
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# XOR.
|
|
110
|
+
#
|
|
111
|
+
# @return [Selector]
|
|
112
|
+
def ^(other)
|
|
113
|
+
if Utils.is_column(other)
|
|
114
|
+
other = by_name(other.meta.output_name)
|
|
115
|
+
end
|
|
116
|
+
if Utils.is_selector(other)
|
|
117
|
+
Selector._from_rbselector(
|
|
118
|
+
_rbselector.exclusive_or(other._rbselector)
|
|
119
|
+
)
|
|
120
|
+
else
|
|
121
|
+
as_expr ^ other
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Exclude columns from a multi-column expression.
|
|
126
|
+
#
|
|
127
|
+
# Only works after a wildcard or regex column selection, and you cannot provide
|
|
128
|
+
# both string column names *and* dtypes (you may prefer to use selectors instead).
|
|
129
|
+
#
|
|
130
|
+
# @param columns [Object]
|
|
131
|
+
# The name or datatype of the column(s) to exclude. Accepts regular expression
|
|
132
|
+
# input. Regular expressions should start with `^` and end with `$`.
|
|
133
|
+
# @param more_columns [Array]
|
|
134
|
+
# Additional names or datatypes of columns to exclude, specified as positional
|
|
135
|
+
# arguments.
|
|
136
|
+
#
|
|
137
|
+
# @return [Selector]
|
|
138
|
+
#
|
|
139
|
+
# @example Exclude by column name(s):
|
|
140
|
+
# df = Polars::DataFrame.new(
|
|
141
|
+
# {
|
|
142
|
+
# "aa" => [1, 2, 3],
|
|
143
|
+
# "ba" => ["a", "b", nil],
|
|
144
|
+
# "cc" => [nil, 2.5, 1.5]
|
|
145
|
+
# }
|
|
146
|
+
# )
|
|
147
|
+
# df.select(Polars.cs.exclude("ba", "xx"))
|
|
148
|
+
# # =>
|
|
149
|
+
# # shape: (3, 2)
|
|
150
|
+
# # ┌─────┬──────┐
|
|
151
|
+
# # │ aa ┆ cc │
|
|
152
|
+
# # │ --- ┆ --- │
|
|
153
|
+
# # │ i64 ┆ f64 │
|
|
154
|
+
# # ╞═════╪══════╡
|
|
155
|
+
# # │ 1 ┆ null │
|
|
156
|
+
# # │ 2 ┆ 2.5 │
|
|
157
|
+
# # │ 3 ┆ 1.5 │
|
|
158
|
+
# # └─────┴──────┘
|
|
159
|
+
#
|
|
160
|
+
# @example Exclude using a column name, a selector, and a dtype:
|
|
161
|
+
# df.select(Polars.cs.exclude("aa", Polars.cs.string, Polars::UInt32))
|
|
162
|
+
# # =>
|
|
163
|
+
# # shape: (3, 1)
|
|
164
|
+
# # ┌──────┐
|
|
165
|
+
# # │ cc │
|
|
166
|
+
# # │ --- │
|
|
167
|
+
# # │ f64 │
|
|
168
|
+
# # ╞══════╡
|
|
169
|
+
# # │ null │
|
|
170
|
+
# # │ 2.5 │
|
|
171
|
+
# # │ 1.5 │
|
|
172
|
+
# # └──────┘
|
|
173
|
+
def exclude(columns, *more_columns)
|
|
174
|
+
exclude_cols = []
|
|
175
|
+
exclude_dtypes = []
|
|
176
|
+
((columns.is_a?(::Array) ? columns : [columns]) + more_columns).each do |item|
|
|
177
|
+
if item.is_a?(::String)
|
|
178
|
+
exclude_cols << item
|
|
179
|
+
elsif Utils.is_polars_dtype(item)
|
|
180
|
+
exclude_dtypes << item
|
|
181
|
+
else
|
|
182
|
+
msg = (
|
|
183
|
+
"invalid input for `exclude`" +
|
|
184
|
+
"\n\nExpected one or more `str` or `DataType`; found #{item.inspect} instead."
|
|
185
|
+
)
|
|
186
|
+
raise TypeError, msg
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
if exclude_cols.any? && exclude_dtypes.any?
|
|
191
|
+
msg = "cannot exclude by both column name and dtype; use a selector instead"
|
|
192
|
+
raise TypeError, msg
|
|
193
|
+
elsif exclude_dtypes.any?
|
|
194
|
+
self - Selectors.by_dtype(exclude_dtypes)
|
|
195
|
+
else
|
|
196
|
+
self - Selector._by_name(exclude_cols, strict: false, expand_patterns: true)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# Materialize the `selector` as a normal expression.
|
|
201
|
+
#
|
|
202
|
+
# This ensures that the operators `|`, `&`, `~` and `-`
|
|
203
|
+
# are applied on the data and not on the selector sets.
|
|
204
|
+
#
|
|
205
|
+
# @return [Expr]
|
|
206
|
+
#
|
|
207
|
+
# @example Inverting the boolean selector will choose the non-boolean columns:
|
|
208
|
+
# df = Polars::DataFrame.new(
|
|
209
|
+
# {
|
|
210
|
+
# "colx" => ["aa", "bb", "cc"],
|
|
211
|
+
# "coly" => [true, false, true],
|
|
212
|
+
# "colz" => [1, 2, 3]
|
|
213
|
+
# }
|
|
214
|
+
# )
|
|
215
|
+
# df.select(~Polars.cs.boolean)
|
|
216
|
+
# # =>
|
|
217
|
+
# # shape: (3, 2)
|
|
218
|
+
# # ┌──────┬──────┐
|
|
219
|
+
# # │ colx ┆ colz │
|
|
220
|
+
# # │ --- ┆ --- │
|
|
221
|
+
# # │ str ┆ i64 │
|
|
222
|
+
# # ╞══════╪══════╡
|
|
223
|
+
# # │ aa ┆ 1 │
|
|
224
|
+
# # │ bb ┆ 2 │
|
|
225
|
+
# # │ cc ┆ 3 │
|
|
226
|
+
# # └──────┴──────┘
|
|
227
|
+
#
|
|
228
|
+
# @example To invert the *values* in the selected boolean columns, we need to materialize the selector as a standard expression instead:
|
|
229
|
+
# df.select(~Polars.cs.boolean.as_expr)
|
|
230
|
+
# # =>
|
|
231
|
+
# # shape: (3, 1)
|
|
232
|
+
# # ┌───────┐
|
|
233
|
+
# # │ coly │
|
|
234
|
+
# # │ --- │
|
|
235
|
+
# # │ bool │
|
|
236
|
+
# # ╞═══════╡
|
|
237
|
+
# # │ false │
|
|
238
|
+
# # │ true │
|
|
239
|
+
# # │ false │
|
|
240
|
+
# # └───────┘
|
|
241
|
+
def as_expr
|
|
242
|
+
Expr._from_rbexpr(_rbexpr)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|