@@ -209,6 +209,7 @@ def _warn_if_expr_for_literal_arg(
209209 "exp" ,
210210 "extract" ,
211211 "factorial" ,
212+ "file_row_index" ,
212213 "find_in_set" ,
213214 "first_value" ,
214215 "flatten" ,
@@ -224,6 +225,7 @@ def _warn_if_expr_for_literal_arg(
224225 "in_list" ,
225226 "initcap" ,
226227 "inner_product" ,
228+ "input_file_name" ,
227229 "instr" ,
228230 "is_nan" ,
229231 "isnan" ,
@@ -334,6 +336,7 @@ def _warn_if_expr_for_literal_arg(
334336 "power" ,
335337 "quantile_cont" ,
336338 "radians" ,
339+ "rand" ,
337340 "random" ,
338341 "range" ,
339342 "rank" ,
@@ -382,6 +385,7 @@ def _warn_if_expr_for_literal_arg(
382385 "substr" ,
383386 "substr_index" ,
384387 "substring" ,
388+ "substring_index" ,
385389 "sum" ,
386390 "tan" ,
387391 "tanh" ,
@@ -2342,6 +2346,15 @@ def substr_index(string: Expr, delimiter: Expr | str, count: Expr | int) -> Expr
23422346 return Expr (f .substr_index (string .expr , delimiter .expr , count .expr ))
23432347
23442348
2349+ def substring_index (string : Expr , delimiter : Expr | str , count : Expr | int ) -> Expr :
2350+ """Returns an indexed substring.
2351+
2352+ See Also:
2353+ This is an alias for :py:func:`substr_index`.
2354+ """
2355+ return substr_index (string , delimiter , count )
2356+
2357+
23452358def substring (string : Expr , position : Expr | int , length : Expr | int ) -> Expr :
23462359 """Substring from the ``position`` with ``length`` characters.
23472360
@@ -3487,6 +3500,64 @@ def random() -> Expr:
34873500 return Expr (f .random ())
34883501
34893502
3503+ def rand () -> Expr :
3504+ """Returns a random value in the range ``0.0 <= x < 1.0``.
3505+
3506+ See Also:
3507+ This is an alias for :py:func:`random`.
3508+ """
3509+ return random ()
3510+
3511+
3512+ def input_file_name () -> Expr :
3513+ """Returns the path of the file that produced the current row.
3514+
3515+ Only valid inside a scan of a file-backed table; evaluating it anywhere
3516+ else raises an error.
3517+
3518+ Examples:
3519+ >>> import tempfile, os
3520+ >>> import pyarrow as pa, pyarrow.parquet as pq
3521+ >>> tmp = tempfile.mkdtemp()
3522+ >>> path = os.path.join(tmp, "data.parquet")
3523+ >>> pq.write_table(pa.table({"a": [1, 2]}), path)
3524+ >>> ctx = dfn.SessionContext()
3525+ >>> df = ctx.read_parquet(path)
3526+ >>> result = df.select(dfn.functions.input_file_name().alias("f"))
3527+ >>> result.collect_column("f")[0].as_py().endswith("data.parquet")
3528+ True
3529+
3530+ See Also:
3531+ :py:func:`file_row_index`.
3532+ """
3533+ return Expr (f .input_file_name ())
3534+
3535+
3536+ def file_row_index () -> Expr :
3537+ """Returns the zero-based position of the current row within its source file.
3538+
3539+ The index restarts at zero for each file, so rows from different files in one
3540+ scan can share a value. Only valid inside a scan of a Parquet table;
3541+ evaluating it anywhere else raises an error.
3542+
3543+ Examples:
3544+ >>> import tempfile, os
3545+ >>> import pyarrow as pa, pyarrow.parquet as pq
3546+ >>> tmp = tempfile.mkdtemp()
3547+ >>> path = os.path.join(tmp, "data.parquet")
3548+ >>> pq.write_table(pa.table({"a": [10, 20, 30]}), path)
3549+ >>> ctx = dfn.SessionContext()
3550+ >>> df = ctx.read_parquet(path).filter(dfn.col("a") > dfn.lit(10))
3551+ >>> result = df.select(dfn.functions.file_row_index().alias("i"))
3552+ >>> result.collect_column("i").to_pylist()
3553+ [1, 2]
3554+
3555+ See Also:
3556+ :py:func:`input_file_name`.
3557+ """
3558+ return Expr (f .file_row_index ())
3559+
3560+
34903561def array_append (array : Expr , element : Expr ) -> Expr :
34913562 """Appends an element to the end of an array.
34923563
@@ -5335,6 +5406,7 @@ def approx_percentile_cont_with_weight(
53355406def percentile_cont (
53365407 sort_expression : Expr | SortExpr ,
53375408 percentile : float ,
5409+ distinct : bool = False ,
53385410 filter : Expr | None = None ,
53395411) -> Expr :
53405412 """Computes the exact percentile of input values using continuous interpolation.
@@ -5343,11 +5415,12 @@ def percentile_cont(
53435415 percentile value rather than an approximation.
53445416
53455417 If using the builder functions described in ref:`_aggregation` this function ignores
5346- the options ``order_by``, ``null_treatment``, and ``distinct ``.
5418+ the options ``order_by`` and ``null_treatment ``.
53475419
53485420 Args:
53495421 sort_expression: Values for which to find the percentile
53505422 percentile: This must be between 0.0 and 1.0, inclusive
5423+ distinct: If True, duplicate values are removed before computing
53515424 filter: If provided, only compute against rows for which the filter is True
53525425
53535426 Examples:
@@ -5367,23 +5440,38 @@ def percentile_cont(
53675440 ... ).alias("v")])
53685441 >>> result.collect_column("v")[0].as_py()
53695442 3.5
5443+
5444+ >>> df = ctx.from_pydict({"a": [1.0, 1.0, 1.0, 4.0]})
5445+ >>> result = df.aggregate(
5446+ ... [], [dfn.functions.percentile_cont(
5447+ ... dfn.col("a"), 0.5, distinct=True,
5448+ ... ).alias("v")])
5449+ >>> result.collect_column("v")[0].as_py()
5450+ 2.5
53705451 """
53715452 sort_expr_raw = sort_or_default (sort_expression )
53725453 filter_raw = filter .expr if filter is not None else None
5373- return Expr (f .percentile_cont (sort_expr_raw , percentile , filter = filter_raw ))
5454+ return Expr (
5455+ f .percentile_cont (
5456+ sort_expr_raw , percentile , distinct = distinct , filter = filter_raw
5457+ )
5458+ )
53745459
53755460
53765461def quantile_cont (
53775462 sort_expression : Expr | SortExpr ,
53785463 percentile : float ,
5464+ distinct : bool = False ,
53795465 filter : Expr | None = None ,
53805466) -> Expr :
53815467 """Computes the exact percentile of input values using continuous interpolation.
53825468
53835469 See Also:
53845470 This is an alias for :py:func:`percentile_cont`.
53855471 """
5386- return percentile_cont (sort_expression , percentile , filter )
5472+ return percentile_cont (
5473+ sort_expression , percentile , distinct = distinct , filter = filter
5474+ )
53875475
53885476
53895477def array_agg (
@@ -5750,13 +5838,17 @@ def max(expression: Expr, filter: Expr | None = None) -> Expr:
57505838 return Expr (f .max (expression .expr , filter = filter_raw ))
57515839
57525840
5753- def mean (expression : Expr , filter : Expr | None = None ) -> Expr :
5841+ def mean (
5842+ expression : Expr ,
5843+ distinct : bool = False ,
5844+ filter : Expr | None = None ,
5845+ ) -> Expr :
57545846 """Returns the average (mean) value of the argument.
57555847
57565848 See Also:
57575849 This is an alias for :py:func:`avg`.
57585850 """
5759- return avg (expression , filter )
5851+ return avg (expression , distinct = distinct , filter = filter )
57605852
57615853
57625854def median (
@@ -6621,16 +6713,19 @@ def any_value(expression: Expr, filter: Expr | None = None) -> Expr:
66216713 return Expr (f .any_value (expression .expr , filter = filter_raw ))
66226714
66236715
6624- def bit_and (expression : Expr , filter : Expr | None = None ) -> Expr :
6716+ def bit_and (
6717+ expression : Expr , distinct : bool = False , filter : Expr | None = None
6718+ ) -> Expr :
66256719 """Computes the bitwise AND of the argument.
66266720
66276721 This aggregate function will bitwise compare every value in the input partition.
66286722
66296723 If using the builder functions described in ref:`_aggregation` this function ignores
6630- the options ``order_by``, ``null_treatment``, and ``distinct ``.
6724+ the options ``order_by`` and ``null_treatment ``.
66316725
66326726 Args:
66336727 expression: Argument to perform bitwise calculation on
6728+ distinct: If True, evaluate each unique value of expression only once
66346729 filter: If provided, only compute against rows for which the filter is True
66356730
66366731 Examples:
@@ -6653,19 +6748,22 @@ def bit_and(expression: Expr, filter: Expr | None = None) -> Expr:
66536748 5
66546749 """
66556750 filter_raw = filter .expr if filter is not None else None
6656- return Expr (f .bit_and (expression .expr , filter = filter_raw ))
6751+ return Expr (f .bit_and (expression .expr , distinct = distinct , filter = filter_raw ))
66576752
66586753
6659- def bit_or (expression : Expr , filter : Expr | None = None ) -> Expr :
6754+ def bit_or (
6755+ expression : Expr , distinct : bool = False , filter : Expr | None = None
6756+ ) -> Expr :
66606757 """Computes the bitwise OR of the argument.
66616758
66626759 This aggregate function will bitwise compare every value in the input partition.
66636760
66646761 If using the builder functions described in ref:`_aggregation` this function ignores
6665- the options ``order_by``, ``null_treatment``, and ``distinct ``.
6762+ the options ``order_by`` and ``null_treatment ``.
66666763
66676764 Args:
66686765 expression: Argument to perform bitwise calculation on
6766+ distinct: If True, evaluate each unique value of expression only once
66696767 filter: If provided, only compute against rows for which the filter is True
66706768
66716769 Examples:
@@ -6690,7 +6788,7 @@ def bit_or(expression: Expr, filter: Expr | None = None) -> Expr:
66906788 6
66916789 """
66926790 filter_raw = filter .expr if filter is not None else None
6693- return Expr (f .bit_or (expression .expr , filter = filter_raw ))
6791+ return Expr (f .bit_or (expression .expr , distinct = distinct , filter = filter_raw ))
66946792
66956793
66966794def bit_xor (
@@ -7315,6 +7413,7 @@ def ntile(
73157413def string_agg (
73167414 expression : Expr ,
73177415 delimiter : str ,
7416+ distinct : bool = False ,
73187417 filter : Expr | None = None ,
73197418 order_by : list [SortKey ] | SortKey | None = None ,
73207419) -> Expr :
@@ -7325,11 +7424,12 @@ def string_agg(
73257424 their string equivalents.
73267425
73277426 If using the builder functions described in ref:`_aggregation` this function ignores
7328- the options ``distinct`` and ``null_treatment``.
7427+ the option ``null_treatment``.
73297428
73307429 Args:
73317430 expression: Argument to perform bitwise calculation on
73327431 delimiter: Text to place between each value of expression
7432+ distinct: If True, each unique value of expression is included only once
73337433 filter: If provided, only compute against rows for which the filter is True
73347434 order_by: Set the ordering of the expression to evaluate. Accepts
73357435 column names or expressions.
@@ -7352,6 +7452,14 @@ def string_agg(
73527452 ... ).alias("s")])
73537453 >>> result.collect_column("s")[0].as_py()
73547454 'y,z'
7455+
7456+ >>> df = ctx.from_pydict({"a": ["y", "x", "y"]})
7457+ >>> result = df.aggregate(
7458+ ... [], [dfn.functions.string_agg(
7459+ ... dfn.col("a"), ",", distinct=True, order_by="a",
7460+ ... ).alias("s")])
7461+ >>> result.collect_column("s")[0].as_py()
7462+ 'x,y'
73557463 """
73567464 order_by_raw = sort_list_to_raw_sort_list (order_by )
73577465 filter_raw = filter .expr if filter is not None else None
@@ -7360,6 +7468,7 @@ def string_agg(
73607468 f .string_agg (
73617469 expression .expr ,
73627470 delimiter ,
7471+ distinct = distinct ,
73637472 filter = filter_raw ,
73647473 order_by = order_by_raw ,
73657474 )
0 commit comments