diff --git a/polars/polars-lazy/polars-plan/src/dsl/arithmetic.rs b/polars/polars-lazy/polars-plan/src/dsl/arithmetic.rs index 35c0cfd5acd5..a81a92fc37d1 100644 --- a/polars/polars-lazy/polars-plan/src/dsl/arithmetic.rs +++ b/polars/polars-lazy/polars-plan/src/dsl/arithmetic.rs @@ -61,28 +61,28 @@ impl Expr { } } - /// Compute the sine of the given expression - #[cfg(feature = "trigonometry")] - pub fn sin(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Sin)) - } - /// Compute the cosine of the given expression #[cfg(feature = "trigonometry")] pub fn cos(self) -> Self { self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Cos)) } - /// Compute the tangent of the given expression + /// Compute the cotangent of the given expression #[cfg(feature = "trigonometry")] - pub fn tan(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Tan)) + pub fn cot(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Cot)) } - /// Compute the inverse sine of the given expression + /// Compute the sine of the given expression #[cfg(feature = "trigonometry")] - pub fn arcsin(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcSin)) + pub fn sin(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Sin)) + } + + /// Compute the tangent of the given expression + #[cfg(feature = "trigonometry")] + pub fn tan(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Tan)) } /// Compute the inverse cosine of the given expression @@ -91,16 +91,16 @@ impl Expr { self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcCos)) } - /// Compute the inverse tangent of the given expression + /// Compute the inverse sine of the given expression #[cfg(feature = "trigonometry")] - pub fn arctan(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcTan)) + pub fn arcsin(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcSin)) } - /// Compute the hyperbolic sine of the given expression + /// Compute the inverse tangent of the given expression #[cfg(feature = "trigonometry")] - pub fn sinh(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Sinh)) + pub fn arctan(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcTan)) } /// Compute the hyperbolic cosine of the given expression @@ -109,16 +109,16 @@ impl Expr { self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Cosh)) } - /// Compute the hyperbolic tangent of the given expression + /// Compute the hyperbolic sine of the given expression #[cfg(feature = "trigonometry")] - pub fn tanh(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Tanh)) + pub fn sinh(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Sinh)) } - /// Compute the inverse hyperbolic sine of the given expression + /// Compute the hyperbolic tangent of the given expression #[cfg(feature = "trigonometry")] - pub fn arcsinh(self) -> Self { - self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcSinh)) + pub fn tanh(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Tanh)) } /// Compute the inverse hyperbolic cosine of the given expression @@ -127,12 +127,30 @@ impl Expr { self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcCosh)) } + /// Compute the inverse hyperbolic sine of the given expression + #[cfg(feature = "trigonometry")] + pub fn arcsinh(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcSinh)) + } + /// Compute the inverse hyperbolic tangent of the given expression #[cfg(feature = "trigonometry")] pub fn arctanh(self) -> Self { self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::ArcTanh)) } + /// Convert from radians to degrees + #[cfg(feature = "trigonometry")] + pub fn degrees(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Degrees)) + } + + /// Convert from degrees to radians + #[cfg(feature = "trigonometry")] + pub fn radians(self) -> Self { + self.map_private(FunctionExpr::Trigonometry(TrigonometricFunction::Radians)) + } + /// Compute the sign of the given expression #[cfg(feature = "sign")] pub fn sign(self) -> Self { diff --git a/polars/polars-lazy/polars-plan/src/dsl/function_expr/trigonometry.rs b/polars/polars-lazy/polars-plan/src/dsl/function_expr/trigonometry.rs index ef0dca84c239..1810baea576a 100644 --- a/polars/polars-lazy/polars-plan/src/dsl/function_expr/trigonometry.rs +++ b/polars/polars-lazy/polars-plan/src/dsl/function_expr/trigonometry.rs @@ -6,36 +6,42 @@ use super::*; #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Clone, Copy, PartialEq, Debug, Eq, Hash)] pub enum TrigonometricFunction { - Sin, Cos, + Cot, + Sin, Tan, - ArcSin, ArcCos, + ArcSin, ArcTan, - Sinh, Cosh, + Sinh, Tanh, - ArcSinh, ArcCosh, + ArcSinh, ArcTanh, + Degrees, + Radians, } impl Display for TrigonometricFunction { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { use self::*; match self { - TrigonometricFunction::Sin => write!(f, "sin"), TrigonometricFunction::Cos => write!(f, "cos"), + TrigonometricFunction::Cot => write!(f, "cot"), + TrigonometricFunction::Sin => write!(f, "sin"), TrigonometricFunction::Tan => write!(f, "tan"), - TrigonometricFunction::ArcSin => write!(f, "arcsin"), TrigonometricFunction::ArcCos => write!(f, "arccos"), + TrigonometricFunction::ArcSin => write!(f, "arcsin"), TrigonometricFunction::ArcTan => write!(f, "arctan"), - TrigonometricFunction::Sinh => write!(f, "sinh"), TrigonometricFunction::Cosh => write!(f, "cosh"), + TrigonometricFunction::Sinh => write!(f, "sinh"), TrigonometricFunction::Tanh => write!(f, "tanh"), - TrigonometricFunction::ArcSinh => write!(f, "arcsinh"), TrigonometricFunction::ArcCosh => write!(f, "arccosh"), + TrigonometricFunction::ArcSinh => write!(f, "arcsinh"), TrigonometricFunction::ArcTanh => write!(f, "arctanh"), + TrigonometricFunction::Degrees => write!(f, "degrees"), + TrigonometricFunction::Radians => write!(f, "radians"), } } } @@ -72,55 +78,58 @@ where ChunkedArray: IntoSeries, { match trig_function { - TrigonometricFunction::Sin => sin(ca), TrigonometricFunction::Cos => cos(ca), + TrigonometricFunction::Cot => cot(ca), + TrigonometricFunction::Sin => sin(ca), TrigonometricFunction::Tan => tan(ca), - TrigonometricFunction::ArcSin => arcsin(ca), TrigonometricFunction::ArcCos => arccos(ca), + TrigonometricFunction::ArcSin => arcsin(ca), TrigonometricFunction::ArcTan => arctan(ca), - TrigonometricFunction::Sinh => sinh(ca), TrigonometricFunction::Cosh => cosh(ca), + TrigonometricFunction::Sinh => sinh(ca), TrigonometricFunction::Tanh => tanh(ca), - TrigonometricFunction::ArcSinh => arcsinh(ca), TrigonometricFunction::ArcCosh => arccosh(ca), + TrigonometricFunction::ArcSinh => arcsinh(ca), TrigonometricFunction::ArcTanh => arctanh(ca), + TrigonometricFunction::Degrees => degrees(ca), + TrigonometricFunction::Radians => radians(ca), } } -fn sin(ca: &ChunkedArray) -> PolarsResult +fn cos(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.sin()).into_series()) + Ok(ca.apply(|v| v.cos()).into_series()) } -fn cos(ca: &ChunkedArray) -> PolarsResult +fn cot(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.cos()).into_series()) + Ok(ca.apply(|v| v.cos() / v.sin()).into_series()) } -fn tan(ca: &ChunkedArray) -> PolarsResult +fn sin(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.tan()).into_series()) + Ok(ca.apply(|v| v.sin()).into_series()) } -fn arcsin(ca: &ChunkedArray) -> PolarsResult +fn tan(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.asin()).into_series()) + Ok(ca.apply(|v| v.tan()).into_series()) } fn arccos(ca: &ChunkedArray) -> PolarsResult @@ -132,22 +141,22 @@ where Ok(ca.apply(|v| v.acos()).into_series()) } -fn arctan(ca: &ChunkedArray) -> PolarsResult +fn arcsin(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.atan()).into_series()) + Ok(ca.apply(|v| v.asin()).into_series()) } -fn sinh(ca: &ChunkedArray) -> PolarsResult +fn arctan(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.sinh()).into_series()) + Ok(ca.apply(|v| v.atan()).into_series()) } fn cosh(ca: &ChunkedArray) -> PolarsResult @@ -159,22 +168,22 @@ where Ok(ca.apply(|v| v.cosh()).into_series()) } -fn tanh(ca: &ChunkedArray) -> PolarsResult +fn sinh(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.tanh()).into_series()) + Ok(ca.apply(|v| v.sinh()).into_series()) } -fn arcsinh(ca: &ChunkedArray) -> PolarsResult +fn tanh(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, T::Native: Float, ChunkedArray: IntoSeries, { - Ok(ca.apply(|v| v.asinh()).into_series()) + Ok(ca.apply(|v| v.tanh()).into_series()) } fn arccosh(ca: &ChunkedArray) -> PolarsResult @@ -186,6 +195,15 @@ where Ok(ca.apply(|v| v.acosh()).into_series()) } +fn arcsinh(ca: &ChunkedArray) -> PolarsResult +where + T: PolarsFloatType, + T::Native: Float, + ChunkedArray: IntoSeries, +{ + Ok(ca.apply(|v| v.asinh()).into_series()) +} + fn arctanh(ca: &ChunkedArray) -> PolarsResult where T: PolarsFloatType, @@ -194,3 +212,21 @@ where { Ok(ca.apply(|v| v.atanh()).into_series()) } + +fn degrees(ca: &ChunkedArray) -> PolarsResult +where + T: PolarsFloatType, + T::Native: Float, + ChunkedArray: IntoSeries, +{ + Ok(ca.apply(|v| v.to_degrees()).into_series()) +} + +fn radians(ca: &ChunkedArray) -> PolarsResult +where + T: PolarsFloatType, + T::Native: Float, + ChunkedArray: IntoSeries, +{ + Ok(ca.apply(|v| v.to_radians()).into_series()) +} diff --git a/polars/polars-sql/src/functions.rs b/polars/polars-sql/src/functions.rs index ec6f73785b62..7caa6afec856 100644 --- a/polars/polars-sql/src/functions.rs +++ b/polars/polars-sql/src/functions.rs @@ -25,6 +25,46 @@ pub(crate) enum PolarsSqlFunctions { /// SELECT ABS(column_1) from df; /// ``` Abs, + /// SQL 'cos' function + /// ```sql + /// SELECT COS(column_1) from df; + /// ``` + Cos, + /// SQL 'cot' function + /// ```sql + /// SELECT COT(column_1) from df; + /// ``` + Cot, + /// SQL 'sin' function + /// ```sql + /// SELECT SIN(column_1) from df; + /// ``` + Sin, + /// SQL 'tan' function + /// ```sql + /// SELECT TAN(column_1) from df; + /// ``` + Tan, + /// SQL 'cosd' function + /// ```sql + /// SELECT COSD(column_1) from df; + /// ``` + CosD, + /// SQL 'cotd' function + /// ```sql + /// SELECT COTD(column_1) from df; + /// ``` + CotD, + /// SQL 'sind' function + /// ```sql + /// SELECT SIND(column_1) from df; + /// ``` + SinD, + /// SQL 'tand' function + /// ```sql + /// SELECT TAND(column_1) from df; + /// ``` + TanD, /// SQL 'acos' function /// ```sql /// SELECT ACOS(column_1) from df; @@ -40,6 +80,21 @@ pub(crate) enum PolarsSqlFunctions { /// SELECT ATAN(column_1) from df; /// ``` Atan, + /// SQL 'acosd' function + /// ```sql + /// SELECT ACOSD(column_1) from df; + /// ``` + AcosD, + /// SQL 'asind' function + /// ```sql + /// SELECT ASIND(column_1) from df; + /// ``` + AsinD, + /// SQL 'atand' function + /// ```sql + /// SELECT ATAND(column_1) from df; + /// ``` + AtanD, /// SQL 'ceil' function /// ```sql /// SELECT CEIL(column_1) from df; @@ -184,6 +239,16 @@ pub(crate) enum PolarsSqlFunctions { /// SELECT ARRAY_LENGTH(column_1) from df; /// ``` ArrayLength, + /// SQL 'degrees' function + /// ```sql + /// SELECT DEGREES(column_1) from df; + /// ``` + Degrees, + /// SQL 'RADIANS' function + /// ```sql + /// SELECT radians(column_1) from df; + /// ``` + Radians, /// SQL 'array_lower' function /// Returns the minimum value in an array; equivalent to `array_min` /// ```sql @@ -245,6 +310,7 @@ impl PolarsSqlFunctions { &[ "abs", "acos", + "acosd", "array_contains", "array_get", "array_length", @@ -255,11 +321,18 @@ impl PolarsSqlFunctions { "array_unique", "array_upper", "asin", + "asind", "atan", + "atand", "avg", "ceil", "ceiling", + "cos", + "cosd", + "cot", + "cotd", "count", + "degrees", "ends_with", "exp", "first", @@ -277,11 +350,18 @@ impl PolarsSqlFunctions { "max", "min", "pow", + "radians", "round", "rtrim", + "sin", + "sind", "starts_with", "stddev", "sum", + "tan", + "tan", + "tand", + "tand", "unnest", "upper", "variance", @@ -298,9 +378,22 @@ impl TryFrom<&'_ SQLFunction> for PolarsSqlFunctions { // Math functions // ---- "abs" => Self::Abs, + "cos" => Self::Cos, + "cot" => Self::Cot, + "sin" => Self::Sin, + "tan" => Self::Tan, + "cosd" => Self::CosD, + "cotd" => Self::CotD, + "sind" => Self::SinD, + "tand" => Self::TanD, "acos" => Self::Acos, "asin" => Self::Asin, "atan" => Self::Atan, + "acosd" => Self::AcosD, + "asind" => Self::AsinD, + "atand" => Self::AtanD, + "degrees" => Self::Degrees, + "radians" => Self::Radians, "ceil" | "ceiling" => Self::Ceil, "exp" => Self::Exp, "floor" => Self::Floor, @@ -362,9 +455,22 @@ impl SqlFunctionVisitor<'_> { // Math functions // ---- Abs => self.visit_unary(Expr::abs), + Cos => self.visit_unary(Expr::cos), + Cot => self.visit_unary(Expr::cot), + Sin => self.visit_unary(Expr::sin), + Tan => self.visit_unary(Expr::tan), + CosD => self.visit_unary(|e| e.radians().cos()), + CotD => self.visit_unary(|e| e.radians().cot()), + SinD => self.visit_unary(|e| e.radians().sin()), + TanD => self.visit_unary(|e| e.radians().tan()), Acos => self.visit_unary(Expr::arccos), Asin => self.visit_unary(Expr::arcsin), Atan => self.visit_unary(Expr::arctan), + AcosD => self.visit_unary(|e| e.arccos().degrees()), + AsinD => self.visit_unary(|e| e.arcsin().degrees()), + AtanD => self.visit_unary(|e| e.arctan().degrees()), + Degrees => self.visit_unary(Expr::degrees), + Radians => self.visit_unary(Expr::radians), Ceil => self.visit_unary(Expr::ceil), Exp => self.visit_unary(Expr::exp), Floor => self.visit_unary(Expr::floor), diff --git a/py-polars/docs/source/reference/expressions/computation.rst b/py-polars/docs/source/reference/expressions/computation.rst index f2f589e3448a..fcfe98a89e05 100644 --- a/py-polars/docs/source/reference/expressions/computation.rst +++ b/py-polars/docs/source/reference/expressions/computation.rst @@ -23,6 +23,7 @@ Computation Expr.cumprod Expr.cumsum Expr.cumulative_eval + Expr.degrees Expr.diff Expr.dot Expr.entropy @@ -39,6 +40,7 @@ Computation Expr.n_unique Expr.null_count Expr.pct_change + Expr.radians Expr.rank Expr.rolling_apply Expr.rolling_max diff --git a/py-polars/polars/expr/expr.py b/py-polars/polars/expr/expr.py index 76585abb6a47..f19c7108d329 100644 --- a/py-polars/polars/expr/expr.py +++ b/py-polars/polars/expr/expr.py @@ -7289,6 +7289,69 @@ def arctanh(self) -> Self: """ return self._from_pyexpr(self._pyexpr.arctanh()) + def degrees(self) -> Self: + """ + Convert from radians to degrees. + + Returns + ------- + Series of dtype Float64 + + Examples + -------- + >>> import math + >>> df = pl.DataFrame({"a": [x * math.pi for x in range(-4, 5)]}) + >>> df.select(pl.col("a").degrees()) + shape: (9, 1) + ┌────────┐ + │ a │ + │ --- │ + │ f64 │ + ╞════════╡ + │ -720.0 │ + │ -540.0 │ + │ -360.0 │ + │ -180.0 │ + │ 0.0 │ + │ 180.0 │ + │ 360.0 │ + │ 540.0 │ + │ 720.0 │ + └────────┘ + """ + return self._from_pyexpr(self._pyexpr.degrees()) + + def radians(self) -> Self: + """ + Convert from degrees to radians. + + Returns + ------- + Series of dtype Float64 + + Examples + -------- + >>> df = pl.DataFrame({"a": [-720, -540, -360, -180, 0, 180, 360, 540, 720]}) + >>> df.select(pl.col("a").radians()) + shape: (9, 1) + ┌────────────┐ + │ a │ + │ --- │ + │ f64 │ + ╞════════════╡ + │ -12.566371 │ + │ -9.424778 │ + │ -6.283185 │ + │ -3.141593 │ + │ 0.0 │ + │ 3.141593 │ + │ 6.283185 │ + │ 9.424778 │ + │ 12.566371 │ + └────────────┘ + """ + return self._from_pyexpr(self._pyexpr.radians()) + def reshape(self, dimensions: tuple[int, ...]) -> Self: """ Reshape this Expr to a flat Series or a Series of Lists. diff --git a/py-polars/src/expr/general.rs b/py-polars/src/expr/general.rs index a2a86cbc4117..cda264e1ae99 100644 --- a/py-polars/src/expr/general.rs +++ b/py-polars/src/expr/general.rs @@ -459,6 +459,16 @@ impl PyExpr { self.clone().inner.arctanh().into() } + #[cfg(feature = "trigonometry")] + pub fn degrees(&self) -> Self { + self.clone().inner.degrees().into() + } + + #[cfg(feature = "trigonometry")] + pub fn radians(&self) -> Self { + self.clone().inner.radians().into() + } + #[cfg(feature = "sign")] fn sign(&self) -> Self { self.clone().inner.sign().into() diff --git a/py-polars/tests/unit/test_sql.py b/py-polars/tests/unit/test_sql.py index b3b0d05687a0..ad764b8950a5 100644 --- a/py-polars/tests/unit/test_sql.py +++ b/py-polars/tests/unit/test_sql.py @@ -113,6 +113,225 @@ def test_sql_equal_not_equal() -> None: } +def test_sql_trig() -> None: + df = pl.DataFrame( + { + "a": [-4, -3, -2, -1.00001, 0, 1.00001, 2, 3, 4], + } + ) + + c = pl.SQLContext(df=df) + res = c.execute( + """ + SELECT + asin(1.0)/a as "pi values", + cos(asin(1.0)/a) AS "cos", + cot(asin(1.0)/a) AS "cot", + sin(asin(1.0)/a) AS "sin", + tan(asin(1.0)/a) AS "tan", + + cosd(asind(1.0)/a) AS "cosd", + cotd(asind(1.0)/a) AS "cotd", + sind(asind(1.0)/a) AS "sind", + tand(asind(1.0)/a) AS "tand", + + 1.0/a as "inverse pi values", + acos(1.0/a) AS "acos", + asin(1.0/a) AS "asin", + atan(1.0/a) AS "atan", + + acosd(1.0/a) AS "acosd", + asind(1.0/a) AS "asind", + atand(1.0/a) AS "atand" + FROM df + """, + eager=True, + ) + + df_result = pl.DataFrame( + { + "pi values": [ + -0.392699, + -0.523599, + -0.785398, + -1.570781, + float("inf"), + 1.570781, + 0.785398, + 0.523599, + 0.392699, + ], + "cos": [ + 0.92388, + 0.866025, + 0.707107, + 0.000016, + float("NaN"), + 0.000016, + 0.707107, + 0.866025, + 0.92388, + ], + "cot": [ + -2.414214, + -1.732051, + -1.0, + -0.000016, + float("NaN"), + 0.000016, + 1.0, + 1.732051, + 2.414214, + ], + "sin": [ + -0.382683, + -0.5, + -0.707107, + -1.0, + float("NaN"), + 1, + 0.707107, + 0.5, + 0.382683, + ], + "tan": [ + -0.414214, + -0.57735, + -1, + -63662.613851, + float("NaN"), + 63662.613851, + 1, + 0.57735, + 0.414214, + ], + "cosd": [ + 0.92388, + 0.866025, + 0.707107, + 0.000016, + float("NaN"), + 0.000016, + 0.707107, + 0.866025, + 0.92388, + ], + "cotd": [ + -2.414214, + -1.732051, + -1.0, + -0.000016, + float("NaN"), + 0.000016, + 1.0, + 1.732051, + 2.414214, + ], + "sind": [ + -0.382683, + -0.5, + -0.707107, + -1.0, + float("NaN"), + 1, + 0.707107, + 0.5, + 0.382683, + ], + "tand": [ + -0.414214, + -0.57735, + -1, + -63662.613851, + float("NaN"), + 63662.613851, + 1, + 0.57735, + 0.414214, + ], + "inverse pi values": [ + -0.25, + -0.333333, + -0.5, + -0.99999, + float("inf"), + 0.99999, + 0.5, + 0.333333, + 0.25, + ], + "acos": [ + 1.823477, + 1.910633, + 2.094395, + 3.137121, + float("NaN"), + 0.004472, + 1.047198, + 1.230959, + 1.318116, + ], + "asin": [ + -0.25268, + -0.339837, + -0.523599, + -1.566324, + float("NaN"), + 1.566324, + 0.523599, + 0.339837, + 0.25268, + ], + "atan": [ + -0.244979, + -0.321751, + -0.463648, + -0.785393, + 1.570796, + 0.785393, + 0.463648, + 0.321751, + 0.244979, + ], + "acosd": [ + 104.477512, + 109.471221, + 120.0, + 179.743767, + float("NaN"), + 0.256233, + 60.0, + 70.528779, + 75.522488, + ], + "asind": [ + -14.477512, + -19.471221, + -30.0, + -89.743767, + float("NaN"), + 89.743767, + 30.0, + 19.471221, + 14.477512, + ], + "atand": [ + -14.036243, + -18.434949, + -26.565051, + -44.999714, + 90.0, + 44.999714, + 26.565051, + 18.434949, + 14.036243, + ], + } + ) + + assert_frame_equal(left=df_result, right=res, atol=1e-5) + + def test_sql_groupby(foods_ipc_path: Path) -> None: lf = pl.scan_ipc(foods_ipc_path)