Arithmetic
polars_ta.wq.arithmetic
除了使用概率极高的几个函数,其他函数不再对常量做lit
Functions:
| Name | Description |
|---|---|
abs_ |
求绝对值 |
add |
水平多列相加 |
arc_cos |
反余弦 |
arc_sin |
反正弦 |
arc_tan |
反正切 |
arc_tan2 |
反正切二值函数 |
cbrt |
立方根 |
ceiling |
向上取整 |
cos |
余弦 |
cosh |
双曲余弦 |
cot |
余切 |
cube |
立方 |
degrees |
弧度转角度 |
div |
x除以y的整数部分 |
divide |
除法 |
exp |
自然指数函数 |
expm1 |
对数收益率 转 简单收益率 |
floor |
向下取整 |
fraction |
小数部分 |
inverse |
倒数 |
log |
以e为底的对数 |
log10 |
以10为底的对数 |
log1p |
简单收益率 转 对数收益率 |
log2 |
以2为底的对数 |
max_ |
水平多列求最大值 |
mean |
水平多列求均值 |
min_ |
水平多列求最小值 |
mod |
求余 |
multiply |
水平多列相乘 |
power |
乘幂 |
radians |
角度转弧度 |
reverse |
求相反数 |
round_ |
四舍五入 |
round_down |
小于输入的f的最大倍数 |
s_log_1p |
sign(x) * log10(1 + abs(x)) |
sign |
符号函数 |
signed_power |
x的y次幂,符号保留 |
sin |
正弦 |
sinh |
双曲正弦 |
softsign |
softsign激活函数 |
sqrt |
平方根 |
square |
平方 |
std |
水平多列求标准差 |
subtract |
减法 |
tan |
正切 |
tanh |
双曲正切 |
var |
水平多列求方差 |
abs_(x: Expr) -> Expr
求绝对值
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 1, 2],
}).with_columns(
out1=abs_(pl.col('a')),
out2=abs_(-1),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out1 ┆ out2 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i32 │
╞══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ 1 │
│ -1 ┆ -1 ┆ 1 ┆ 1 │
│ 0 ┆ 0 ┆ 0 ┆ 1 │
│ 1 ┆ 1 ┆ 1 ┆ 1 │
│ 2 ┆ 2 ┆ 2 ┆ 1 │
└──────┴──────┴──────┴──────┘
add(a: Expr, b: Expr, *args) -> Expr
水平多列相加
Examples:
df = pl.DataFrame({
'a': [None, 2, 3, 4, None],
'b': [5, None, 3, 2, None],
'c': [1, 1, None, 1, None],
}).with_columns(
out=add(pl.col('a'), pl.col('b'), pl.col('c'))
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ c ┆ out │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪══════╡
│ null ┆ 5 ┆ 1 ┆ 6 │
│ 2 ┆ null ┆ 1 ┆ 3 │
│ 3 ┆ 3 ┆ null ┆ 6 │
│ 4 ┆ 2 ┆ 1 ┆ 7 │
│ null ┆ null ┆ null ┆ null │
└──────┴──────┴──────┴──────┘
Notes
全null时返回null
arc_cos(x: Expr) -> Expr
反余弦
arc_sin(x: Expr) -> Expr
反正弦
arc_tan(x: Expr) -> Expr
反正切
arc_tan2(y: Expr, x: Expr) -> Expr
反正切二值函数
cbrt(x: Expr) -> Expr
立方根
ceiling(x: Expr) -> Expr
向上取整
cos(x: Expr) -> Expr
余弦
cosh(x: Expr) -> Expr
双曲余弦
cot(x: Expr) -> Expr
余切
cube(x: Expr) -> Expr
立方
degrees(x: Expr) -> Expr
弧度转角度
div(x: Expr, y: Expr) -> Expr
x除以y的整数部分
Examples:
df = pl.DataFrame({
'a': [None, -1.5, 0., 1.5, 2.5],
'b': [None, -1, 0, 1, 2],
}).with_columns(
out1=div(pl.col('a'), 0),
out2=div(pl.col('a'), 1),
out3=div(pl.col('a'), pl.col('b')),
)
shape: (5, 5)
┌──────┬──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out1 ┆ out2 ┆ out3 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ f64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null ┆ null │
│ -1.5 ┆ -1 ┆ null ┆ -2 ┆ 1 │
│ 0.0 ┆ 0 ┆ null ┆ 0 ┆ null │
│ 1.5 ┆ 1 ┆ null ┆ 1 ┆ 1 │
│ 2.5 ┆ 2 ┆ null ┆ 2 ┆ 1 │
└──────┴──────┴──────┴──────┴──────┘
divide(x: Expr, y: Expr) -> Expr
除法
x/y
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 1, 2],
}).with_columns(
out1=divide(pl.col('a'), 0),
out2=divide(pl.col('a'), 1),
out3=divide(pl.col('a'), pl.col('b')),
)
shape: (5, 5)
┌──────┬──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out1 ┆ out2 ┆ out3 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ f64 ┆ f64 ┆ f64 │
╞══════╪══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null ┆ null │
│ -1 ┆ -1 ┆ -inf ┆ -1.0 ┆ 1.0 │
│ 0 ┆ 0 ┆ NaN ┆ 0.0 ┆ NaN │
│ 1 ┆ 1 ┆ inf ┆ 1.0 ┆ 1.0 │
│ 2 ┆ 2 ┆ inf ┆ 2.0 ┆ 1.0 │
└──────┴──────┴──────┴──────┴──────┘
exp(x: Expr) -> Expr
自然指数函数
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=expm1(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════════╡
│ null ┆ null │
│ -1 ┆ 0.367879 │
│ 0 ┆ 1.0 │
│ 1 ┆ 2.718282 │
│ 2 ┆ 7.389056 │
└──────┴──────────┘
expm1(x: Expr) -> Expr
对数收益率 转 简单收益率
convert log return to simple return
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=expm1(pl.col('a')),
)
shape: (5, 2)
┌──────┬───────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪═══════════╡
│ null ┆ null │
│ -1 ┆ -0.632121 │
│ 0 ┆ 0.0 │
│ 1 ┆ 1.718282 │
│ 2 ┆ 6.389056 │
└──────┴───────────┘
floor(x: Expr) -> Expr
向下取整
fraction(x: Expr) -> Expr
小数部分
This operator removes the whole number part and returns the remaining fraction part with sign.
Examples:
df = pl.DataFrame({
'a': [-2.5, -1.2, -1., None, 2., 3.2],
}).with_columns(
out=fraction(pl.col('a'))
)
shape: (6, 2)
┌──────┬──────┐
│ a ┆ out │
│ --- ┆ --- │
│ f64 ┆ f64 │
╞══════╪══════╡
│ -2.5 ┆ -0.5 │
│ -1.2 ┆ -0.2 │
│ -1.0 ┆ -0.0 │
│ null ┆ null │
│ 2.0 ┆ 0.0 │
│ 3.2 ┆ 0.2 │
└──────┴──────┘
Notes
按小学时的定义,负数-1.2的整数部分是-2,小数部分是0.8,而这有所不同
References
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#fractionx
inverse(x: Expr) -> Expr
倒数
1/x
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=inverse(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════╡
│ null ┆ null │
│ -1 ┆ -1.0 │
│ 0 ┆ inf │
│ 1 ┆ 1.0 │
│ 2 ┆ 0.5 │
└──────┴──────┘
log(x: Expr) -> Expr
以e为底的对数
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=log(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════════╡
│ null ┆ null │
│ -1 ┆ NaN │
│ 0 ┆ -inf │
│ 1 ┆ 0.0 │
│ 2 ┆ 0.693147 │
└──────┴──────────┘
log10(x: Expr) -> Expr
以10为底的对数
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=log10(pl.col('a')),
)
shape: (5, 2)
┌──────┬─────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪═════════╡
│ null ┆ null │
│ -1 ┆ NaN │
│ 0 ┆ -inf │
│ 1 ┆ 0.0 │
│ 2 ┆ 0.30103 │
└──────┴─────────┘
log1p(x: Expr) -> Expr
简单收益率 转 对数收益率
convert simple return to log return
log(x+1)
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=log1p(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════════╡
│ null ┆ null │
│ -1 ┆ -inf │
│ 0 ┆ 0.0 │
│ 1 ┆ 0.693147 │
│ 2 ┆ 1.098612 │
└──────┴──────────┘
log2(x: Expr) -> Expr
以2为底的对数
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=log2(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════╡
│ null ┆ null │
│ -1 ┆ NaN │
│ 0 ┆ -inf │
│ 1 ┆ 0.0 │
│ 2 ┆ 1.0 │
└──────┴──────┘
max_(a: Expr, b: Expr, *args) -> Expr
水平多列求最大值
Maximum value of all inputs. At least 2 inputs are required.
mean(a: Expr, b: Expr, *args) -> Expr
水平多列求均值
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 0, 2],
}).with_columns(
out2=mean(pl.col('a'), 2),
out3=mean(pl.col('a'), pl.col('b')),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out2 ┆ out3 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ f64 ┆ f64 │
╞══════╪══════╪══════╪══════╡
│ null ┆ null ┆ 2.0 ┆ null │
│ -1 ┆ -1 ┆ 0.5 ┆ -1.0 │
│ 0 ┆ 0 ┆ 1.0 ┆ 0.0 │
│ 1 ┆ 0 ┆ 1.5 ┆ 0.5 │
│ 2 ┆ 2 ┆ 2.0 ┆ 2.0 │
└──────┴──────┴──────┴──────┘
min_(a: Expr, b: Expr, *args) -> Expr
水平多列求最小值
Maximum value of all inputs. At least 2 inputs are required.
mod(x: Expr, y: Expr) -> Expr
求余
x%y
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 0, 2],
}).with_columns(
out2=mod(pl.col('a'), 2),
out3=mod(pl.col('a'), pl.col('b')),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out2 ┆ out3 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null │
│ -1 ┆ -1 ┆ 1 ┆ 0 │
│ 0 ┆ 0 ┆ 0 ┆ null │
│ 1 ┆ 0 ┆ 1 ┆ null │
│ 2 ┆ 2 ┆ 0 ┆ 0 │
└──────┴──────┴──────┴──────┘
multiply(a: Expr, b: Expr, *args) -> Expr
水平多列相乘
Multiply all inputs. At least 2 inputs are required.
Examples:
df = pl.DataFrame({
'a': [None, 2, 3, 4, None],
'b': [5, None, 3, 2, None],
'c': [1, 1, None, 1, None],
}).with_columns(
out=multiply(pl.col('a'), pl.col('b'), pl.col('c'))
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ c ┆ out │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 │
╞══════╪══════╪══════╪══════╡
│ null ┆ 5 ┆ 1 ┆ 5 │
│ 2 ┆ null ┆ 1 ┆ 2 │
│ 3 ┆ 3 ┆ null ┆ 9 │
│ 4 ┆ 2 ┆ 1 ┆ 8 │
│ null ┆ null ┆ null ┆ null │
└──────┴──────┴──────┴──────┘
Notes
全null时返回null
power(x: Expr, y: Expr) -> Expr
乘幂
x ** y
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 1, 2],
}).with_columns(
out2=power(pl.col('a'), 1),
out3=power(pl.col('a'), pl.col('b')),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out2 ┆ out3 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 │
╞══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null │
│ -1 ┆ -1 ┆ -1 ┆ -1.0 │
│ 0 ┆ 0 ┆ 0 ┆ 1.0 │
│ 1 ┆ 1 ┆ 1 ┆ 1.0 │
│ 2 ┆ 2 ┆ 2 ┆ 4.0 │
└──────┴──────┴──────┴──────┘
Notes
负数的非整数幂在实数中未定义
radians(x: Expr) -> Expr
角度转弧度
reverse(x: Expr) -> Expr
求相反数
round_(x: Expr, decimals: int = 0) -> Expr
四舍五入
Round input to closest integer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Expr
|
|
required |
decimals
|
int
|
Number of decimals to round to. |
0
|
Examples:
df = pl.DataFrame({
'a': [None, 3.5, 4.5, -3.5, -4.5],
}).with_columns(
out1=round_(pl.col('a'), 0),
out2=pl.col('a').map_elements(lambda x: round(x, 0), return_dtype=pl.Float64),
)
shape: (5, 3)
┌──────┬──────┬──────┐
│ a ┆ out1 ┆ out2 │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞══════╪══════╪══════╡
│ null ┆ null ┆ null │
│ 3.5 ┆ 4.0 ┆ 4.0 │
│ 4.5 ┆ 5.0 ┆ 4.0 │
│ -3.5 ┆ -4.0 ┆ -4.0 │
│ -4.5 ┆ -5.0 ┆ -4.0 │
└──────┴──────┴──────┘
Notes
四舍五入,不是四舍六入五取偶(银行家舍入)
round_down(x: Expr, f: int = 1) -> Expr
小于输入的f的最大倍数
Round input to greatest multiple of f less than input
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Expr
|
|
required |
f
|
int
|
|
1
|
Examples:
df = pl.DataFrame({
'a': [None, 3.5, 4.5, -3.5, -4.5],
}).with_columns(
out=round_down(pl.col('a'), 2),
)
shape: (5, 2)
┌──────┬──────┐
│ a ┆ out │
│ --- ┆ --- │
│ f64 ┆ f64 │
╞══════╪══════╡
│ null ┆ null │
│ 3.5 ┆ 2.0 │
│ 4.5 ┆ 4.0 │
│ -3.5 ┆ -4.0 │
│ -4.5 ┆ -6.0 │
└──────┴──────┘
s_log_1p(x: Expr) -> Expr
sign(x) * log10(1 + abs(x))
一种结合符号函数和对数变换的复合函数,常用于保留数据符号的同时压缩数值范围
Examples:
df = pl.DataFrame({
'a': [None, 9, -9, 99, -99],
}).with_columns(
out1=s_log_1p(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════╡
│ null ┆ null │
│ 9 ┆ 1.0 │
│ -9 ┆ -1.0 │
│ 99 ┆ 2.0 │
│ -99 ┆ -2.0 │
└──────┴──────┘
Notes
从wq示例可以看出,log的底数是10,而不是e
References
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#s_log_1px
sign(x: Expr) -> Expr
符号函数
signed_power(x: Expr, y: Expr) -> Expr
x的y次幂,符号保留
x raised to the power of y such that final result preserves sign of x.
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
'b': [None, -1, 0, 1, 2],
}).with_columns(
out1=signed_power(pl.col('a'), 0),
out2=signed_power(pl.col('a'), 1),
out3=signed_power(pl.col('a'), 2),
out4=signed_power(pl.col('a'), pl.col('b')),
)
shape: (5, 6)
┌──────┬──────┬──────┬──────┬──────┬──────┐
│ a ┆ b ┆ out1 ┆ out2 ┆ out3 ┆ out4 │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ i64 ┆ i64 ┆ f64 │
╞══════╪══════╪══════╪══════╪══════╪══════╡
│ null ┆ null ┆ null ┆ null ┆ null ┆ null │
│ -1 ┆ -1 ┆ -1 ┆ -1 ┆ -1 ┆ -1.0 │
│ 0 ┆ 0 ┆ 0 ┆ 0 ┆ 0 ┆ 0.0 │
│ 1 ┆ 1 ┆ 1 ┆ 1 ┆ 1 ┆ 1.0 │
│ 2 ┆ 2 ┆ 1 ┆ 2 ┆ 4 ┆ 4.0 │
└──────┴──────┴──────┴──────┴──────┴──────┘
References
https://platform.worldquantbrain.com/learn/operators/detailed-operator-descriptions#signed_powerx-y
sin(x: Expr) -> Expr
正弦
sinh(x: Expr) -> Expr
双曲正弦
softsign(x: Expr) -> Expr
softsign激活函数
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=softsign(pl.col('a')),
)
shape: (5, 2)
┌──────┬──────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪══════════╡
│ null ┆ null │
│ -1 ┆ -0.5 │
│ 0 ┆ 0.0 │
│ 1 ┆ 0.5 │
│ 2 ┆ 0.666667 │
└──────┴──────────┘
sqrt(x: Expr) -> Expr
平方根
square(x: Expr) -> Expr
平方
std(a: Expr, b: Expr, *args) -> Expr
水平多列求标准差
Examples:
df = pl.DataFrame({
'a': [None, -1, 1, 1, 2],
'b': [None, -1, 0, 1, 2],
'c': [None, -1, 0, 2, None],
}).with_columns(
out2=std(pl.col('a'), pl.col('b'), pl.col('c')),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────────┐
│ a ┆ b ┆ c ┆ out2 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 │
╞══════╪══════╪══════╪══════════╡
│ null ┆ null ┆ null ┆ 0.0 │
│ -1 ┆ -1 ┆ -1 ┆ 0.0 │
│ 1 ┆ 0 ┆ 0 ┆ 0.816497 │
│ 1 ┆ 1 ┆ 2 ┆ 0.816497 │
│ 2 ┆ 2 ┆ null ┆ 0.0 │
└──────┴──────┴──────┴──────────┘
subtract(x: Expr, y: Expr) -> Expr
减法
x-y
tan(x: Expr) -> Expr
正切
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=tan(pl.col('a')),
)
shape: (5, 2)
┌──────┬───────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪═══════════╡
│ null ┆ null │
│ -1 ┆ -1.557408 │
│ 0 ┆ 0.0 │
│ 1 ┆ 1.557408 │
│ 2 ┆ -2.18504 │
└──────┴───────────┘
tanh(x: Expr) -> Expr
双曲正切
Examples:
df = pl.DataFrame({
'a': [None, -1, 0, 1, 2],
}).with_columns(
out1=tanh(pl.col('a')),
)
shape: (5, 2)
┌──────┬───────────┐
│ a ┆ out1 │
│ --- ┆ --- │
│ i64 ┆ f64 │
╞══════╪═══════════╡
│ null ┆ null │
│ -1 ┆ -0.761594 │
│ 0 ┆ 0.0 │
│ 1 ┆ 0.761594 │
│ 2 ┆ 0.964028 │
└──────┴───────────┘
var(a: Expr, b: Expr, *args) -> Expr
水平多列求方差
Examples:
df = pl.DataFrame({
'a': [None, -1, 1, 1, 2],
'b': [None, -1, 0, 1, 2],
'c': [None, -1, 0, 2, None],
}).with_columns(
out1=var(pl.col('a'), pl.col('b'), pl.col('c')),
)
shape: (5, 4)
┌──────┬──────┬──────┬──────────┐
│ a ┆ b ┆ c ┆ out1 │
│ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ i64 ┆ f64 │
╞══════╪══════╪══════╪══════════╡
│ null ┆ null ┆ null ┆ 0.0 │
│ -1 ┆ -1 ┆ -1 ┆ 0.0 │
│ 1 ┆ 0 ┆ 0 ┆ 0.666667 │
│ 1 ┆ 1 ┆ 2 ┆ 0.666667 │
│ 2 ┆ 2 ┆ null ┆ 0.0 │
└──────┴──────┴──────┴──────────┘