@@ -74,6 +74,20 @@ def _forbid_instantiation(klass, subclasses_instead=True):
7474 raise TypeError (msg)
7575
7676
77+ cdef vector[CSortKey] unwrap_sort_keys(sort_keys, allow_str = True ):
78+ cdef vector[CSortKey] c_sort_keys
79+ if allow_str and isinstance (sort_keys, str ):
80+ c_sort_keys.push_back(
81+ CSortKey(_ensure_field_ref(" " ), unwrap_sort_order(sort_keys))
82+ )
83+ else :
84+ for name, order in sort_keys:
85+ c_sort_keys.push_back(
86+ CSortKey(_ensure_field_ref(name), unwrap_sort_order(order))
87+ )
88+ return c_sort_keys
89+
90+
7791cdef wrap_scalar_function(const shared_ptr[CFunction]& sp_func):
7892 """
7993 Wrap a C++ scalar Function in a ScalarFunction object.
@@ -2093,13 +2107,9 @@ class ArraySortOptions(_ArraySortOptions):
20932107
20942108cdef class _SortOptions(FunctionOptions):
20952109 def _set_options (self , sort_keys , null_placement ):
2096- cdef vector[CSortKey] c_sort_keys
2097- for name, order in sort_keys:
2098- c_sort_keys.push_back(
2099- CSortKey(_ensure_field_ref(name), unwrap_sort_order(order))
2100- )
21012110 self .wrapped.reset(new CSortOptions(
2102- c_sort_keys, unwrap_null_placement(null_placement)))
2111+ unwrap_sort_keys(sort_keys, allow_str = False ),
2112+ unwrap_null_placement(null_placement)))
21032113
21042114
21052115class SortOptions (_SortOptions ):
@@ -2125,12 +2135,7 @@ class SortOptions(_SortOptions):
21252135
21262136cdef class _SelectKOptions(FunctionOptions):
21272137 def _set_options (self , k , sort_keys ):
2128- cdef vector[CSortKey] c_sort_keys
2129- for name, order in sort_keys:
2130- c_sort_keys.push_back(
2131- CSortKey(_ensure_field_ref(name), unwrap_sort_order(order))
2132- )
2133- self .wrapped.reset(new CSelectKOptions(k, c_sort_keys))
2138+ self .wrapped.reset(new CSelectKOptions(k, unwrap_sort_keys(sort_keys, allow_str = False )))
21342139
21352140
21362141class SelectKOptions (_SelectKOptions ):
@@ -2317,19 +2322,9 @@ cdef class _RankOptions(FunctionOptions):
23172322 }
23182323
23192324 def _set_options (self , sort_keys , null_placement , tiebreaker ):
2320- cdef vector[CSortKey] c_sort_keys
2321- if isinstance (sort_keys, str ):
2322- c_sort_keys.push_back(
2323- CSortKey(_ensure_field_ref(" " ), unwrap_sort_order(sort_keys))
2324- )
2325- else :
2326- for name, order in sort_keys:
2327- c_sort_keys.push_back(
2328- CSortKey(_ensure_field_ref(name), unwrap_sort_order(order))
2329- )
23302325 try :
23312326 self .wrapped.reset(
2332- new CRankOptions(c_sort_keys ,
2327+ new CRankOptions(unwrap_sort_keys(sort_keys) ,
23332328 unwrap_null_placement(null_placement),
23342329 self ._tiebreaker_map[tiebreaker])
23352330 )
@@ -2370,6 +2365,37 @@ class RankOptions(_RankOptions):
23702365 self ._set_options(sort_keys, null_placement, tiebreaker)
23712366
23722367
2368+ cdef class _RankQuantileOptions(FunctionOptions):
2369+
2370+ def _set_options (self , sort_keys , null_placement ):
2371+ self .wrapped.reset(
2372+ new CRankQuantileOptions(unwrap_sort_keys(sort_keys),
2373+ unwrap_null_placement(null_placement))
2374+ )
2375+
2376+
2377+ class RankQuantileOptions (_RankQuantileOptions ):
2378+ """
2379+ Options for the `rank_quantile` function.
2380+
2381+ Parameters
2382+ ----------
2383+ sort_keys : sequence of (name, order) tuples or str, default "ascending"
2384+ Names of field/column keys to sort the input on,
2385+ along with the order each field/column is sorted in.
2386+ Accepted values for `order` are "ascending", "descending".
2387+ The field name can be a string column name or expression.
2388+ Alternatively, one can simply pass "ascending" or "descending" as a string
2389+ if the input is array-like.
2390+ null_placement : str, default "at_end"
2391+ Where nulls in input should be sorted.
2392+ Accepted values are "at_start", "at_end".
2393+ """
2394+
2395+ def __init__ (self , sort_keys = " ascending" , *, null_placement = " at_end" ):
2396+ self ._set_options(sort_keys, null_placement)
2397+
2398+
23732399cdef class Expression(_Weakrefable):
23742400 """
23752401 A logical expression to be evaluated against some input.
0 commit comments