Skip to content

Commit 6193669

Browse files
authored
Add support for interpolate_by (#100)
1 parent 09ec6af commit 6193669

File tree

6 files changed

+68
-0
lines changed

6 files changed

+68
-0
lines changed

ext/polars/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ features = [
6363
"gcp",
6464
"http",
6565
"interpolate",
66+
"interpolate_by",
6667
"ipc",
6768
"ipc_streaming",
6869
"is_between",

ext/polars/src/expr/general.rs

+4
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,10 @@ impl RbExpr {
671671
self.inner.clone().interpolate(method.0).into()
672672
}
673673

674+
pub fn interpolate_by(&self, by: &Self) -> Self {
675+
self.inner.clone().interpolate_by(by.inner.clone()).into()
676+
}
677+
674678
pub fn lower_bound(&self) -> Self {
675679
self.inner.clone().lower_bound().into()
676680
}

ext/polars/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ fn init(ruby: &Ruby) -> RbResult<()> {
430430
class.define_method("mode", method!(RbExpr::mode, 0))?;
431431
class.define_method("exclude", method!(RbExpr::exclude, 1))?;
432432
class.define_method("interpolate", method!(RbExpr::interpolate, 1))?;
433+
class.define_method("interpolate_by", method!(RbExpr::interpolate_by, 1))?;
433434
class.define_method("rolling_sum", method!(RbExpr::rolling_sum, 4))?;
434435
class.define_method("rolling_sum_by", method!(RbExpr::rolling_sum_by, 4))?;
435436
class.define_method("rolling_min", method!(RbExpr::rolling_min, 4))?;

lib/polars/expr.rb

+31
Original file line numberDiff line numberDiff line change
@@ -3994,6 +3994,37 @@ def interpolate(method: "linear")
39943994
_from_rbexpr(_rbexpr.interpolate(method))
39953995
end
39963996

3997+
# Fill null values using interpolation based on another column.
3998+
#
3999+
# @return [Expr]
4000+
#
4001+
# @param by [Expr] Column to interpolate values based on.
4002+
#
4003+
# @example Fill null values using linear interpolation.
4004+
# df = Polars::DataFrame.new(
4005+
# {
4006+
# "a" => [1, nil, nil, 3],
4007+
# "b" => [1, 2, 7, 8]
4008+
# }
4009+
# )
4010+
# df.with_columns(a_interpolated: Polars.col("a").interpolate_by("b"))
4011+
# # =>
4012+
# # shape: (4, 3)
4013+
# # ┌──────┬─────┬────────────────┐
4014+
# # │ a ┆ b ┆ a_interpolated │
4015+
# # │ --- ┆ --- ┆ --- │
4016+
# # │ i64 ┆ i64 ┆ f64 │
4017+
# # ╞══════╪═════╪════════════════╡
4018+
# # │ 1 ┆ 1 ┆ 1.0 │
4019+
# # │ null ┆ 2 ┆ 1.285714 │
4020+
# # │ null ┆ 7 ┆ 2.714286 │
4021+
# # │ 3 ┆ 8 ┆ 3.0 │
4022+
# # └──────┴─────┴────────────────┘
4023+
def interpolate_by(by)
4024+
by = Utils.parse_into_expression(by)
4025+
_from_rbexpr(_rbexpr.interpolate_by(by))
4026+
end
4027+
39974028
# Apply a rolling min based on another column.
39984029
#
39994030
# @param by [String]

lib/polars/series.rb

+24
Original file line numberDiff line numberDiff line change
@@ -3815,6 +3815,30 @@ def interpolate(method: "linear")
38153815
super
38163816
end
38173817

3818+
# Fill null values using interpolation based on another column.
3819+
#
3820+
# @param by [Expr]
3821+
# Column to interpolate values based on.
3822+
#
3823+
# @return [Series]
3824+
#
3825+
# @example Fill null values using linear interpolation.
3826+
# s = Polars::Series.new("a", [1, nil, nil, 3])
3827+
# by = Polars::Series.new("b", [1, 2, 7, 8])
3828+
# s.interpolate_by(by)
3829+
# # =>
3830+
# # shape: (4,)
3831+
# # Series: 'a' [f64]
3832+
# # [
3833+
# # 1.0
3834+
# # 1.285714
3835+
# # 2.714286
3836+
# # 3.0
3837+
# # ]
3838+
def interpolate_by(by)
3839+
super
3840+
end
3841+
38183842
# Compute absolute values.
38193843
#
38203844
# @return [Series]

test/series_test.rb

+7
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,13 @@ def test_interpolate
734734
assert_series [1, 2, 3, 4, 5], s.interpolate
735735
end
736736

737+
def test_interpolate_by
738+
s = Polars::Series.new("a", [1, nil, nil, 3])
739+
by = Polars::Series.new("b", [1, 2, 7, 8])
740+
s.interpolate_by(by)
741+
assert_series [1.0, 1.2857142857142856, 2.7142857142857144, 3.0], s.interpolate_by(by)
742+
end
743+
737744
def test_shrink_to_fit
738745
s = Polars::Series.new([1, 2, 3])
739746
s.shrink_to_fit

0 commit comments

Comments
 (0)