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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/Cargo.lock +270 -97
- data/LICENSE.txt +1 -1
- data/README.md +1 -3
- data/ext/polars/Cargo.toml +19 -18
- data/ext/polars/src/catalog/unity.rs +15 -20
- data/ext/polars/src/conversion/any_value.rs +53 -29
- data/ext/polars/src/conversion/chunked_array.rs +58 -56
- data/ext/polars/src/conversion/datetime.rs +58 -7
- data/ext/polars/src/conversion/mod.rs +200 -150
- data/ext/polars/src/dataframe/export.rs +15 -12
- data/ext/polars/src/dataframe/general.rs +25 -7
- data/ext/polars/src/dataframe/map.rs +6 -4
- data/ext/polars/src/error.rs +1 -1
- data/ext/polars/src/expr/array.rs +0 -24
- data/ext/polars/src/expr/datatype.rs +13 -3
- data/ext/polars/src/expr/datetime.rs +4 -4
- data/ext/polars/src/expr/general.rs +35 -15
- data/ext/polars/src/expr/list.rs +0 -26
- data/ext/polars/src/expr/rolling.rs +24 -0
- data/ext/polars/src/functions/business.rs +2 -2
- data/ext/polars/src/functions/io.rs +4 -3
- data/ext/polars/src/functions/lazy.rs +65 -46
- data/ext/polars/src/functions/meta.rs +6 -5
- data/ext/polars/src/functions/mod.rs +0 -1
- data/ext/polars/src/functions/range.rs +13 -0
- data/ext/polars/src/functions/utils.rs +4 -2
- data/ext/polars/src/interop/arrow/mod.rs +4 -2
- data/ext/polars/src/interop/arrow/to_rb.rs +1 -1
- data/ext/polars/src/interop/numo/to_numo_series.rs +26 -25
- data/ext/polars/src/io/scan_options.rs +6 -3
- data/ext/polars/src/io/sink_options.rs +2 -0
- data/ext/polars/src/lazyframe/general.rs +243 -17
- data/ext/polars/src/lazyframe/optflags.rs +2 -1
- data/ext/polars/src/lib.rs +39 -35
- data/ext/polars/src/map/lazy.rs +5 -2
- data/ext/polars/src/map/series.rs +19 -18
- data/ext/polars/src/on_startup.rs +25 -6
- data/ext/polars/src/ruby/numo.rs +3 -4
- data/ext/polars/src/ruby/plan_callback.rs +1 -4
- data/ext/polars/src/ruby/rb_modules.rs +2 -4
- data/ext/polars/src/ruby/ruby_udf.rs +7 -9
- data/ext/polars/src/ruby/utils.rs +12 -1
- data/ext/polars/src/series/aggregation.rs +13 -1
- data/ext/polars/src/series/construction.rs +31 -50
- data/ext/polars/src/series/export.rs +33 -38
- data/ext/polars/src/series/general.rs +6 -6
- data/ext/polars/src/series/map.rs +3 -2
- data/ext/polars/src/series/scatter.rs +4 -4
- data/ext/polars/src/utils.rs +31 -7
- data/lib/polars/array_expr.rb +23 -7
- data/lib/polars/array_name_space.rb +16 -2
- data/lib/polars/binary_name_space.rb +32 -0
- data/lib/polars/collect_batches.rb +4 -0
- data/lib/polars/data_frame.rb +144 -11
- data/lib/polars/data_type_group.rb +5 -0
- data/lib/polars/date_time_expr.rb +91 -3
- data/lib/polars/date_time_name_space.rb +7 -1
- data/lib/polars/expr.rb +247 -44
- data/lib/polars/functions/business.rb +2 -2
- data/lib/polars/functions/datatype.rb +30 -0
- data/lib/polars/functions/eager.rb +80 -7
- data/lib/polars/functions/lazy.rb +97 -2
- data/lib/polars/functions/range/linear_space.rb +118 -0
- data/lib/polars/io/csv.rb +27 -5
- data/lib/polars/io/database.rb +2 -3
- data/lib/polars/io/ipc.rb +2 -2
- data/lib/polars/io/lines.rb +172 -0
- data/lib/polars/io/parquet.rb +1 -1
- data/lib/polars/io/sink_options.rb +5 -2
- data/lib/polars/lazy_frame.rb +517 -14
- data/lib/polars/list_expr.rb +21 -7
- data/lib/polars/list_name_space.rb +16 -2
- data/lib/polars/query_opt_flags.rb +23 -5
- data/lib/polars/selectors.rb +2 -2
- data/lib/polars/series.rb +176 -19
- data/lib/polars/sql_context.rb +2 -2
- data/lib/polars/string_cache.rb +19 -72
- data/lib/polars/string_expr.rb +1 -7
- data/lib/polars/string_name_space.rb +1 -7
- data/lib/polars/utils/construction/series.rb +24 -39
- data/lib/polars/utils/convert.rb +16 -6
- data/lib/polars/utils/parse.rb +7 -0
- data/lib/polars/utils/reduce_balanced.rb +43 -0
- data/lib/polars/utils/various.rb +5 -0
- data/lib/polars/version.rb +1 -1
- data/lib/polars.rb +2 -1
- metadata +4 -17
- data/ext/polars/src/functions/string_cache.rs +0 -24
data/lib/polars/data_frame.rb
CHANGED
|
@@ -3808,6 +3808,57 @@ module Polars
|
|
|
3808
3808
|
.collect(optimizations: QueryOptFlags._eager)
|
|
3809
3809
|
end
|
|
3810
3810
|
|
|
3811
|
+
# Selects rows from this DataFrame at the given indices.
|
|
3812
|
+
#
|
|
3813
|
+
# @note
|
|
3814
|
+
# This functionality is experimental. It may be
|
|
3815
|
+
# changed at any point without it being considered a breaking change.
|
|
3816
|
+
#
|
|
3817
|
+
# @param indices [Object]
|
|
3818
|
+
# The indices of the rows to select.
|
|
3819
|
+
# @param null_on_oob [Boolean]
|
|
3820
|
+
# If true when an index is out-of-bounds a null row will be generated
|
|
3821
|
+
# instead of raising an error.
|
|
3822
|
+
#
|
|
3823
|
+
# @return [DataFrame]
|
|
3824
|
+
#
|
|
3825
|
+
# @example
|
|
3826
|
+
# df = Polars::DataFrame.new({"x" => [2, 1, 0], "s" => ["foo", "bar", "baz"]})
|
|
3827
|
+
# df.gather([2, 0, 0])
|
|
3828
|
+
# # =>
|
|
3829
|
+
# # shape: (3, 2)
|
|
3830
|
+
# # ┌─────┬─────┐
|
|
3831
|
+
# # │ x ┆ s │
|
|
3832
|
+
# # │ --- ┆ --- │
|
|
3833
|
+
# # │ i64 ┆ str │
|
|
3834
|
+
# # ╞═════╪═════╡
|
|
3835
|
+
# # │ 0 ┆ baz │
|
|
3836
|
+
# # │ 2 ┆ foo │
|
|
3837
|
+
# # │ 2 ┆ foo │
|
|
3838
|
+
# # └─────┴─────┘
|
|
3839
|
+
#
|
|
3840
|
+
# @example
|
|
3841
|
+
# df.gather([0, 10, 1], null_on_oob: true)
|
|
3842
|
+
# # =>
|
|
3843
|
+
# # shape: (3, 2)
|
|
3844
|
+
# # ┌──────┬──────┐
|
|
3845
|
+
# # │ x ┆ s │
|
|
3846
|
+
# # │ --- ┆ --- │
|
|
3847
|
+
# # │ i64 ┆ str │
|
|
3848
|
+
# # ╞══════╪══════╡
|
|
3849
|
+
# # │ 2 ┆ foo │
|
|
3850
|
+
# # │ null ┆ null │
|
|
3851
|
+
# # │ 1 ┆ bar │
|
|
3852
|
+
# # └──────┴──────┘
|
|
3853
|
+
def gather(
|
|
3854
|
+
indices,
|
|
3855
|
+
null_on_oob: false
|
|
3856
|
+
)
|
|
3857
|
+
lazy
|
|
3858
|
+
.gather(indices, null_on_oob: null_on_oob)
|
|
3859
|
+
.collect(optimizations: QueryOptFlags._eager)
|
|
3860
|
+
end
|
|
3861
|
+
|
|
3811
3862
|
# Apply a custom/user-defined function (UDF) over the rows of the DataFrame.
|
|
3812
3863
|
#
|
|
3813
3864
|
# The UDF will receive each row as a tuple of values: `udf(row)`.
|
|
@@ -4527,6 +4578,8 @@ module Polars
|
|
|
4527
4578
|
# @param separator [String]
|
|
4528
4579
|
# Used as separator/delimiter in generated column names in case of multiple
|
|
4529
4580
|
# `values` columns.
|
|
4581
|
+
# @param column_naming ['auto', 'combine']
|
|
4582
|
+
# How resulting column names will be constructed.
|
|
4530
4583
|
#
|
|
4531
4584
|
# @return [DataFrame]
|
|
4532
4585
|
#
|
|
@@ -4557,7 +4610,8 @@ module Polars
|
|
|
4557
4610
|
aggregate_function: nil,
|
|
4558
4611
|
maintain_order: true,
|
|
4559
4612
|
sort_columns: false,
|
|
4560
|
-
separator: "_"
|
|
4613
|
+
separator: "_",
|
|
4614
|
+
column_naming: "auto"
|
|
4561
4615
|
)
|
|
4562
4616
|
if on_columns.nil?
|
|
4563
4617
|
cols = select(on).unique(maintain_order: true)
|
|
@@ -4577,7 +4631,8 @@ module Polars
|
|
|
4577
4631
|
values: values,
|
|
4578
4632
|
aggregate_function: aggregate_function,
|
|
4579
4633
|
maintain_order: maintain_order,
|
|
4580
|
-
separator: separator
|
|
4634
|
+
separator: separator,
|
|
4635
|
+
column_naming: column_naming
|
|
4581
4636
|
)
|
|
4582
4637
|
.collect(optimizations: QueryOptFlags._eager)
|
|
4583
4638
|
end
|
|
@@ -4593,7 +4648,8 @@ module Polars
|
|
|
4593
4648
|
#
|
|
4594
4649
|
# @param on [Object]
|
|
4595
4650
|
# Column(s) or selector(s) to use as values variables; if `on`
|
|
4596
|
-
# is empty
|
|
4651
|
+
# is empty no columns will be used. If set to `nil` (default)
|
|
4652
|
+
# all columns that are not in `index` will be used.
|
|
4597
4653
|
# @param index [Object]
|
|
4598
4654
|
# Column(s) or selector(s) to use as identifier variables.
|
|
4599
4655
|
# @param variable_name [Object]
|
|
@@ -4627,7 +4683,7 @@ module Polars
|
|
|
4627
4683
|
# # │ z ┆ c ┆ 6 │
|
|
4628
4684
|
# # └─────┴──────────┴───────┘
|
|
4629
4685
|
def unpivot(on = nil, index: nil, variable_name: nil, value_name: nil)
|
|
4630
|
-
on = on.nil? ?
|
|
4686
|
+
on = on.nil? ? nil : Utils._expand_selectors(self, on)
|
|
4631
4687
|
index = index.nil? ? [] : Utils._expand_selectors(self, index)
|
|
4632
4688
|
|
|
4633
4689
|
_from_rbdf(_df.unpivot(on, index, value_name, variable_name))
|
|
@@ -6448,7 +6504,7 @@ module Polars
|
|
|
6448
6504
|
# # {5,"five"}
|
|
6449
6505
|
# # ]
|
|
6450
6506
|
def to_struct(name = "")
|
|
6451
|
-
Utils.wrap_s(_df.to_struct(name))
|
|
6507
|
+
Utils.wrap_s(_df.to_struct(name, []))
|
|
6452
6508
|
end
|
|
6453
6509
|
|
|
6454
6510
|
# Decompose a struct into its fields.
|
|
@@ -6488,7 +6544,7 @@ module Polars
|
|
|
6488
6544
|
# # │ foo ┆ 1 ┆ a ┆ true ┆ [1, 2] ┆ baz │
|
|
6489
6545
|
# # │ bar ┆ 2 ┆ b ┆ null ┆ [3] ┆ womp │
|
|
6490
6546
|
# # └────────┴─────┴─────┴──────┴───────────┴───────┘
|
|
6491
|
-
def unnest(columns, *more_columns, separator: nil)
|
|
6547
|
+
def unnest(columns = nil, *more_columns, separator: nil)
|
|
6492
6548
|
lazy.unnest(columns, *more_columns, separator: separator).collect(optimizations: QueryOptFlags._eager)
|
|
6493
6549
|
end
|
|
6494
6550
|
|
|
@@ -6504,6 +6560,10 @@ module Polars
|
|
|
6504
6560
|
# Other DataFrame that must be merged
|
|
6505
6561
|
# @param key [String]
|
|
6506
6562
|
# Key that is sorted.
|
|
6563
|
+
# @param maintain_order [Boolean]
|
|
6564
|
+
# If `true`, the output is guaranteed to have left-biased ordering
|
|
6565
|
+
# for equal keys: rows from the left frame appear before rows from
|
|
6566
|
+
# the right frame when their keys are equal.
|
|
6507
6567
|
#
|
|
6508
6568
|
# @return [DataFrame]
|
|
6509
6569
|
#
|
|
@@ -6530,8 +6590,8 @@ module Polars
|
|
|
6530
6590
|
# # │ steve ┆ 42 │
|
|
6531
6591
|
# # │ elise ┆ 44 │
|
|
6532
6592
|
# # └────────┴─────┘
|
|
6533
|
-
def merge_sorted(other, key)
|
|
6534
|
-
lazy.merge_sorted(other.lazy, key).collect(optimizations: QueryOptFlags._eager)
|
|
6593
|
+
def merge_sorted(other, key, maintain_order: false)
|
|
6594
|
+
lazy.merge_sorted(other.lazy, key, maintain_order: maintain_order).collect(optimizations: QueryOptFlags._eager)
|
|
6535
6595
|
end
|
|
6536
6596
|
|
|
6537
6597
|
# Flag a column as sorted.
|
|
@@ -6545,14 +6605,17 @@ module Polars
|
|
|
6545
6605
|
# Column that is sorted.
|
|
6546
6606
|
# @param descending [Boolean]
|
|
6547
6607
|
# Whether the column is sorted in descending order.
|
|
6608
|
+
# @param nulls_last [Boolean]
|
|
6609
|
+
# Whether the nulls are at the end.
|
|
6548
6610
|
#
|
|
6549
6611
|
# @return [DataFrame]
|
|
6550
6612
|
def set_sorted(
|
|
6551
6613
|
column,
|
|
6552
|
-
descending: false
|
|
6614
|
+
descending: false,
|
|
6615
|
+
nulls_last: false
|
|
6553
6616
|
)
|
|
6554
6617
|
lazy
|
|
6555
|
-
.set_sorted(column, descending: descending)
|
|
6618
|
+
.set_sorted(column, descending: descending, nulls_last: nulls_last)
|
|
6556
6619
|
.collect(optimizations: QueryOptFlags._eager)
|
|
6557
6620
|
end
|
|
6558
6621
|
|
|
@@ -6687,6 +6750,76 @@ module Polars
|
|
|
6687
6750
|
.collect(optimizations: QueryOptFlags._eager)
|
|
6688
6751
|
end
|
|
6689
6752
|
|
|
6753
|
+
# Match or evolve the schema of a LazyFrame into a specific schema.
|
|
6754
|
+
#
|
|
6755
|
+
# By default, match_to_schema returns an error if the input schema does not
|
|
6756
|
+
# exactly match the target schema. It also allows columns to be freely reordered,
|
|
6757
|
+
# with additional coercion rules available through optional parameters.
|
|
6758
|
+
#
|
|
6759
|
+
# @note
|
|
6760
|
+
# This functionality is considered **unstable**. It may be changed
|
|
6761
|
+
# at any point without it being considered a breaking change.
|
|
6762
|
+
#
|
|
6763
|
+
# @param schema [Object]
|
|
6764
|
+
# Target schema to match or evolve to.
|
|
6765
|
+
# @param missing_columns [Object]
|
|
6766
|
+
# Raise of insert missing columns from the input with respect to the `schema`.
|
|
6767
|
+
#
|
|
6768
|
+
# This can also be an expression per column with what to insert if it is
|
|
6769
|
+
# missing.
|
|
6770
|
+
# @param missing_struct_fields [Object]
|
|
6771
|
+
# Raise of insert missing struct fields from the input with respect to the
|
|
6772
|
+
# `schema`.
|
|
6773
|
+
# @param extra_columns [Object]
|
|
6774
|
+
# Raise of ignore extra columns from the input with respect to the `schema`.
|
|
6775
|
+
# @param extra_struct_fields [Object]
|
|
6776
|
+
# Raise of ignore extra struct fields from the input with respect to the
|
|
6777
|
+
# `schema`.
|
|
6778
|
+
# @param integer_cast [Object]
|
|
6779
|
+
# Forbid of upcast for integer columns from the input to the respective column
|
|
6780
|
+
# in `schema`.
|
|
6781
|
+
# @param float_cast [Object]
|
|
6782
|
+
# Forbid of upcast for float columns from the input to the respective column
|
|
6783
|
+
# in `schema`.
|
|
6784
|
+
#
|
|
6785
|
+
# @return [DataFrame]
|
|
6786
|
+
#
|
|
6787
|
+
# @example Ensuring the schema matches
|
|
6788
|
+
# df = Polars::DataFrame.new({"a" => [1, 2, 3], "b" => ["A", "B", "C"]})
|
|
6789
|
+
# df.match_to_schema({"a" => Polars::Int64, "b" => Polars::String})
|
|
6790
|
+
# # =>
|
|
6791
|
+
# # shape: (3, 2)
|
|
6792
|
+
# # ┌─────┬─────┐
|
|
6793
|
+
# # │ a ┆ b │
|
|
6794
|
+
# # │ --- ┆ --- │
|
|
6795
|
+
# # │ i64 ┆ str │
|
|
6796
|
+
# # ╞═════╪═════╡
|
|
6797
|
+
# # │ 1 ┆ A │
|
|
6798
|
+
# # │ 2 ┆ B │
|
|
6799
|
+
# # │ 3 ┆ C │
|
|
6800
|
+
# # └─────┴─────┘
|
|
6801
|
+
def match_to_schema(
|
|
6802
|
+
schema,
|
|
6803
|
+
missing_columns: "raise",
|
|
6804
|
+
missing_struct_fields: "raise",
|
|
6805
|
+
extra_columns: "raise",
|
|
6806
|
+
extra_struct_fields: "raise",
|
|
6807
|
+
integer_cast: "forbid",
|
|
6808
|
+
float_cast: "forbid"
|
|
6809
|
+
)
|
|
6810
|
+
lazy
|
|
6811
|
+
.match_to_schema(
|
|
6812
|
+
schema,
|
|
6813
|
+
missing_columns: missing_columns,
|
|
6814
|
+
missing_struct_fields: missing_struct_fields,
|
|
6815
|
+
extra_columns: extra_columns,
|
|
6816
|
+
extra_struct_fields: extra_struct_fields,
|
|
6817
|
+
integer_cast: integer_cast,
|
|
6818
|
+
float_cast: float_cast
|
|
6819
|
+
)
|
|
6820
|
+
.collect(optimizations: QueryOptFlags._eager)
|
|
6821
|
+
end
|
|
6822
|
+
|
|
6690
6823
|
private
|
|
6691
6824
|
|
|
6692
6825
|
def initialize_copy(other)
|
|
@@ -7041,7 +7174,7 @@ module Polars
|
|
|
7041
7174
|
end
|
|
7042
7175
|
|
|
7043
7176
|
def _select_rows_by_slice(df, key)
|
|
7044
|
-
|
|
7177
|
+
Slice.new(df).apply(key)
|
|
7045
7178
|
end
|
|
7046
7179
|
|
|
7047
7180
|
def _select_rows_by_index(df, key)
|
|
@@ -3,6 +3,7 @@ module Polars
|
|
|
3
3
|
class DataTypeGroup < Set
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
+
# @private
|
|
6
7
|
SIGNED_INTEGER_DTYPES = DataTypeGroup.new(
|
|
7
8
|
[
|
|
8
9
|
Int8,
|
|
@@ -11,6 +12,7 @@ module Polars
|
|
|
11
12
|
Int64
|
|
12
13
|
]
|
|
13
14
|
)
|
|
15
|
+
# @private
|
|
14
16
|
UNSIGNED_INTEGER_DTYPES = DataTypeGroup.new(
|
|
15
17
|
[
|
|
16
18
|
UInt8,
|
|
@@ -19,10 +21,13 @@ module Polars
|
|
|
19
21
|
UInt64
|
|
20
22
|
]
|
|
21
23
|
)
|
|
24
|
+
# @private
|
|
22
25
|
INTEGER_DTYPES = (
|
|
23
26
|
SIGNED_INTEGER_DTYPES | UNSIGNED_INTEGER_DTYPES
|
|
24
27
|
)
|
|
28
|
+
# @private
|
|
25
29
|
FLOAT_DTYPES = DataTypeGroup.new([Float32, Float64])
|
|
30
|
+
# @private
|
|
26
31
|
NUMERIC_DTYPES = DataTypeGroup.new(
|
|
27
32
|
FLOAT_DTYPES + INTEGER_DTYPES | [Decimal]
|
|
28
33
|
)
|
|
@@ -22,6 +22,8 @@ module Polars
|
|
|
22
22
|
# Which days of the week to count. The default is Monday to Friday.
|
|
23
23
|
# If you wanted to count only Monday to Thursday, you would pass
|
|
24
24
|
# `[true, true, true, true, false, false, false]`.
|
|
25
|
+
# @param holidays [Object]
|
|
26
|
+
# Holidays to exclude from the count.
|
|
25
27
|
# @param roll
|
|
26
28
|
# What to do when the start date lands on a non-business day. Options are:
|
|
27
29
|
#
|
|
@@ -44,17 +46,67 @@ module Polars
|
|
|
44
46
|
# # │ 2020-01-01 ┆ 2020-01-08 │
|
|
45
47
|
# # │ 2020-01-02 ┆ 2020-01-09 │
|
|
46
48
|
# # └────────────┴────────────┘
|
|
49
|
+
#
|
|
50
|
+
# @example You can pass a custom weekend - for example, if you only take Sunday off:
|
|
51
|
+
# week_mask = [true, true, true, true, true, true, false]
|
|
52
|
+
# df.with_columns(
|
|
53
|
+
# result: Polars.col("start").dt.add_business_days(5, week_mask: week_mask)
|
|
54
|
+
# )
|
|
55
|
+
# # =>
|
|
56
|
+
# # shape: (2, 2)
|
|
57
|
+
# # ┌────────────┬────────────┐
|
|
58
|
+
# # │ start ┆ result │
|
|
59
|
+
# # │ --- ┆ --- │
|
|
60
|
+
# # │ date ┆ date │
|
|
61
|
+
# # ╞════════════╪════════════╡
|
|
62
|
+
# # │ 2020-01-01 ┆ 2020-01-07 │
|
|
63
|
+
# # │ 2020-01-02 ┆ 2020-01-08 │
|
|
64
|
+
# # └────────────┴────────────┘
|
|
65
|
+
#
|
|
66
|
+
# @example You can also pass a list of holidays:
|
|
67
|
+
# holidays = [Date.new(2020, 1, 3), Date.new(2020, 1, 6)]
|
|
68
|
+
# df.with_columns(
|
|
69
|
+
# result: Polars.col("start").dt.add_business_days(5, holidays: holidays)
|
|
70
|
+
# )
|
|
71
|
+
# # =>
|
|
72
|
+
# # shape: (2, 2)
|
|
73
|
+
# # ┌────────────┬────────────┐
|
|
74
|
+
# # │ start ┆ result │
|
|
75
|
+
# # │ --- ┆ --- │
|
|
76
|
+
# # │ date ┆ date │
|
|
77
|
+
# # ╞════════════╪════════════╡
|
|
78
|
+
# # │ 2020-01-01 ┆ 2020-01-10 │
|
|
79
|
+
# # │ 2020-01-02 ┆ 2020-01-13 │
|
|
80
|
+
# # └────────────┴────────────┘
|
|
81
|
+
#
|
|
82
|
+
# @example Roll all dates forwards to the next business day:
|
|
83
|
+
# df = Polars::DataFrame.new({"start" => [Date.new(2020, 1, 5), Date.new(2020, 1, 6)]})
|
|
84
|
+
# df.with_columns(
|
|
85
|
+
# rolled_forwards: Polars.col("start").dt.add_business_days(0, roll: "forward")
|
|
86
|
+
# )
|
|
87
|
+
# # =>
|
|
88
|
+
# # shape: (2, 2)
|
|
89
|
+
# # ┌────────────┬─────────────────┐
|
|
90
|
+
# # │ start ┆ rolled_forwards │
|
|
91
|
+
# # │ --- ┆ --- │
|
|
92
|
+
# # │ date ┆ date │
|
|
93
|
+
# # ╞════════════╪═════════════════╡
|
|
94
|
+
# # │ 2020-01-05 ┆ 2020-01-06 │
|
|
95
|
+
# # │ 2020-01-06 ┆ 2020-01-06 │
|
|
96
|
+
# # └────────────┴─────────────────┘
|
|
47
97
|
def add_business_days(
|
|
48
98
|
n,
|
|
49
99
|
week_mask: [true, true, true, true, true, false, false],
|
|
100
|
+
holidays: [],
|
|
50
101
|
roll: "raise"
|
|
51
102
|
)
|
|
52
103
|
n_rbexpr = Utils.parse_into_expression(n)
|
|
104
|
+
holidays_rbexpr = Utils._holidays_to_expr(holidays)
|
|
53
105
|
Utils.wrap_expr(
|
|
54
106
|
_rbexpr.dt_add_business_days(
|
|
55
107
|
n_rbexpr,
|
|
56
108
|
week_mask,
|
|
57
|
-
|
|
109
|
+
holidays_rbexpr,
|
|
58
110
|
roll
|
|
59
111
|
)
|
|
60
112
|
)
|
|
@@ -580,6 +632,8 @@ module Polars
|
|
|
580
632
|
# Which days of the week to count. The default is Monday to Friday.
|
|
581
633
|
# If you wanted to count only Monday to Thursday, you would pass
|
|
582
634
|
# `[true, true, true, true, false, false, false]`.
|
|
635
|
+
# @param holidays [Object]
|
|
636
|
+
# Holidays to exclude from the count.
|
|
583
637
|
#
|
|
584
638
|
# @return [Expr]
|
|
585
639
|
#
|
|
@@ -596,13 +650,47 @@ module Polars
|
|
|
596
650
|
# # │ 2020-01-03 ┆ true │
|
|
597
651
|
# # │ 2020-01-05 ┆ false │
|
|
598
652
|
# # └────────────┴─────────────────┘
|
|
653
|
+
#
|
|
654
|
+
# @example You can pass a custom weekend - for example, if you only take Sunday off:
|
|
655
|
+
# week_mask = [true, true, true, true, true, true, false]
|
|
656
|
+
# df.with_columns(
|
|
657
|
+
# is_business_day: Polars.col("start").dt.is_business_day(week_mask: week_mask)
|
|
658
|
+
# )
|
|
659
|
+
# # =>
|
|
660
|
+
# # shape: (2, 2)
|
|
661
|
+
# # ┌────────────┬─────────────────┐
|
|
662
|
+
# # │ start ┆ is_business_day │
|
|
663
|
+
# # │ --- ┆ --- │
|
|
664
|
+
# # │ date ┆ bool │
|
|
665
|
+
# # ╞════════════╪═════════════════╡
|
|
666
|
+
# # │ 2020-01-03 ┆ true │
|
|
667
|
+
# # │ 2020-01-05 ┆ false │
|
|
668
|
+
# # └────────────┴─────────────────┘
|
|
669
|
+
#
|
|
670
|
+
# @example You can also pass a list of holidays:
|
|
671
|
+
# holidays = [Date.new(2020, 1, 3), Date.new(2020, 1, 6)]
|
|
672
|
+
# df.with_columns(
|
|
673
|
+
# is_business_day: Polars.col("start").dt.is_business_day(holidays: holidays)
|
|
674
|
+
# )
|
|
675
|
+
# # =>
|
|
676
|
+
# # shape: (2, 2)
|
|
677
|
+
# # ┌────────────┬─────────────────┐
|
|
678
|
+
# # │ start ┆ is_business_day │
|
|
679
|
+
# # │ --- ┆ --- │
|
|
680
|
+
# # │ date ┆ bool │
|
|
681
|
+
# # ╞════════════╪═════════════════╡
|
|
682
|
+
# # │ 2020-01-03 ┆ false │
|
|
683
|
+
# # │ 2020-01-05 ┆ false │
|
|
684
|
+
# # └────────────┴─────────────────┘
|
|
599
685
|
def is_business_day(
|
|
600
|
-
week_mask: [true, true, true, true, true, false, false]
|
|
686
|
+
week_mask: [true, true, true, true, true, false, false],
|
|
687
|
+
holidays: []
|
|
601
688
|
)
|
|
689
|
+
holidays_rbexpr = Utils._holidays_to_expr(holidays)
|
|
602
690
|
Utils.wrap_expr(
|
|
603
691
|
_rbexpr.dt_is_business_day(
|
|
604
692
|
week_mask,
|
|
605
|
-
|
|
693
|
+
holidays_rbexpr
|
|
606
694
|
)
|
|
607
695
|
)
|
|
608
696
|
end
|
|
@@ -31,6 +31,8 @@ module Polars
|
|
|
31
31
|
# Which days of the week to count. The default is Monday to Friday.
|
|
32
32
|
# If you wanted to count only Monday to Thursday, you would pass
|
|
33
33
|
# `[true, true, true, true, false, false, false]`.
|
|
34
|
+
# @param holidays [Object]
|
|
35
|
+
# Holidays to exclude from the count.
|
|
34
36
|
# roll
|
|
35
37
|
# What to do when the start date lands on a non-business day. Options are:
|
|
36
38
|
#
|
|
@@ -75,6 +77,7 @@ module Polars
|
|
|
75
77
|
def add_business_days(
|
|
76
78
|
n,
|
|
77
79
|
week_mask: [true, true, true, true, true, false, false],
|
|
80
|
+
holidays: [],
|
|
78
81
|
roll: "raise"
|
|
79
82
|
)
|
|
80
83
|
super
|
|
@@ -263,6 +266,8 @@ module Polars
|
|
|
263
266
|
# Which days of the week to count. The default is Monday to Friday.
|
|
264
267
|
# If you wanted to count only Monday to Thursday, you would pass
|
|
265
268
|
# `[true, true, true, true, false, false, false]`.
|
|
269
|
+
# @param holidays [Object]
|
|
270
|
+
# Holidays to exclude from the count.
|
|
266
271
|
#
|
|
267
272
|
# @return [Series]
|
|
268
273
|
#
|
|
@@ -288,7 +293,8 @@ module Polars
|
|
|
288
293
|
# # false
|
|
289
294
|
# # ]
|
|
290
295
|
def is_business_day(
|
|
291
|
-
week_mask: [true, true, true, true, true, false, false]
|
|
296
|
+
week_mask: [true, true, true, true, true, false, false],
|
|
297
|
+
holidays: []
|
|
292
298
|
)
|
|
293
299
|
super
|
|
294
300
|
end
|