PySpark-Column-Selectors 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PySparkSelectors/__init__.py +240 -0
- PySparkSelectors/__main__.py +4 -0
- PySparkSelectors/cli.py +18 -0
- PySparkSelectors/models.py +1564 -0
- PySparkSelectors/py.typed +1 -0
- PySparkSelectors/spark_overrides.py +677 -0
- PySparkSelectors/user_functions.py +745 -0
- PySparkSelectors/utils.py +298 -0
- pyspark_column_selectors-0.1.3.dist-info/METADATA +674 -0
- pyspark_column_selectors-0.1.3.dist-info/RECORD +13 -0
- pyspark_column_selectors-0.1.3.dist-info/WHEEL +4 -0
- pyspark_column_selectors-0.1.3.dist-info/entry_points.txt +2 -0
- pyspark_column_selectors-0.1.3.dist-info/licenses/LICENSE +279 -0
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from collections.abc import Sequence
|
|
3
|
+
from typing import Any, cast
|
|
4
|
+
|
|
5
|
+
import pyspark.sql.types as T
|
|
6
|
+
from pyspark.sql import DataFrame
|
|
7
|
+
from pyspark.sql.column import Column
|
|
8
|
+
|
|
9
|
+
from .models import BaseSelector, DTypeSelector, IndexSelector, RegexSelector
|
|
10
|
+
|
|
11
|
+
_TIMESTAMP_TYPES = tuple(t for t in (T.TimestampType, getattr(T, "TimestampNTZType", None)) if t is not None)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
""" enable support for many different types of pyspark environments"""
|
|
15
|
+
# if your environment isn't supported then you can add it to this section.
|
|
16
|
+
# Spark supports multiple DataFrame implementations. Keep every available runtime
|
|
17
|
+
# class in the patch set: public/classic DataFrame and Spark Connect DataFrame.
|
|
18
|
+
# using try except as to allow passthrough if environment doesn't support these.
|
|
19
|
+
try:
|
|
20
|
+
from pyspark.sql.classic.dataframe import DataFrame as _ClassicDataFrame
|
|
21
|
+
except ImportError:
|
|
22
|
+
_ClassicDataFrame = None
|
|
23
|
+
|
|
24
|
+
try:
|
|
25
|
+
from pyspark.sql.connect.dataframe import DataFrame as _ConnectDataFrame
|
|
26
|
+
except ImportError:
|
|
27
|
+
_ConnectDataFrame = None
|
|
28
|
+
|
|
29
|
+
_DATAFRAME_CLASSES = tuple(
|
|
30
|
+
dict.fromkeys(cls for cls in (DataFrame, _ClassicDataFrame, _ConnectDataFrame) if cls is not None)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
try:
|
|
34
|
+
from pyspark.sql.connect.column import Column as _ConnectColumn
|
|
35
|
+
except ImportError:
|
|
36
|
+
_ConnectColumn = None
|
|
37
|
+
|
|
38
|
+
_COLUMN_CLASSES = tuple(dict.fromkeys(cls for cls in (Column, _ConnectColumn) if cls is not None))
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# --------------------------------------------------------------------------------
|
|
42
|
+
# the layout of functionality is that we have 3 column selector classes that resolve our columns.
|
|
43
|
+
# dtype_selector, index_selector, and regex_selector
|
|
44
|
+
# you will see that each of these above classes has a 1 main function that is used for all selection
|
|
45
|
+
# by_dtype, by_index, and matches.
|
|
46
|
+
# all other column selector functions are built on top of these 3 main functions.
|
|
47
|
+
# --------------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
# --------------------------------------------------------------------------------
|
|
50
|
+
# BY_INDEX SECTION
|
|
51
|
+
# create main by_index function that is used for all index based column selection
|
|
52
|
+
# --------------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def by_index(*indexes: int | range, strict_index_bounds: bool = True, require_col_match: bool = True) -> IndexSelector:
|
|
56
|
+
"""Select columns by positional index.
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
*indexes : int or range
|
|
61
|
+
One or more positional column indexes. Negative ints follow
|
|
62
|
+
Python's own indexing convention (``-1`` = last column). A `range`
|
|
63
|
+
object covers a span in one shot (e.g. ``range(1, 4)`` for columns 1-3).
|
|
64
|
+
strict_index_bounds : bool, default True
|
|
65
|
+
If `True`, an out-of-bounds index raises
|
|
66
|
+
`pyspark.errors.PySparkValueError`. If `False`, out-of-bounds
|
|
67
|
+
indexes are silently skipped.
|
|
68
|
+
require_col_match : bool, default True
|
|
69
|
+
If `True` (default), resolving this selector against a dataframe
|
|
70
|
+
with zero matching columns raises `pyspark.errors.PySparkValueError`.
|
|
71
|
+
Set to `False` to opt out and allow a zero-column match instead
|
|
72
|
+
(only reachable when `strict_index_bounds` is also `False`).
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
IndexSelector
|
|
77
|
+
A selector matching the column(s) at the requested position(s),
|
|
78
|
+
composable with ``~ - & ^ |`` and chainable with arithmetic/spark
|
|
79
|
+
functions.
|
|
80
|
+
|
|
81
|
+
Examples
|
|
82
|
+
--------
|
|
83
|
+
>>> df.select(by_index(0, 1))
|
|
84
|
+
DataFrame[...]
|
|
85
|
+
>>> df.select(by_index(range(1, 4), -1))
|
|
86
|
+
DataFrame[...]
|
|
87
|
+
"""
|
|
88
|
+
return IndexSelector(indexes, strict_index_bounds=strict_index_bounds, require_col_match=require_col_match)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# --------------------------------------------------------------------------------
|
|
92
|
+
# create first column selector from by_index function
|
|
93
|
+
# --------------------------------------------------------------------------------
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def first(require_col_match: bool = True) -> IndexSelector:
|
|
97
|
+
"""Select the first column.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
require_col_match : bool, default True
|
|
102
|
+
Forwarded to `by_index`. Set to `False` to opt out of the
|
|
103
|
+
zero-match error and allow no matching columns.
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
IndexSelector
|
|
108
|
+
Equivalent to ``by_index(0)``.
|
|
109
|
+
|
|
110
|
+
Examples
|
|
111
|
+
--------
|
|
112
|
+
>>> df.select(first())
|
|
113
|
+
DataFrame[...]
|
|
114
|
+
"""
|
|
115
|
+
return by_index(0, require_col_match=require_col_match)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# --------------------------------------------------------------------------------
|
|
119
|
+
# create last column selector from by_dtype function
|
|
120
|
+
# --------------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def last(require_col_match: bool = True) -> IndexSelector:
|
|
124
|
+
"""Select the last column.
|
|
125
|
+
|
|
126
|
+
Parameters
|
|
127
|
+
----------
|
|
128
|
+
require_col_match : bool, default True
|
|
129
|
+
Forwarded to `by_index`. Set to `False` to opt out of the
|
|
130
|
+
zero-match error and allow no matching columns.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
IndexSelector
|
|
135
|
+
Equivalent to ``by_index(-1)``.
|
|
136
|
+
|
|
137
|
+
Examples
|
|
138
|
+
--------
|
|
139
|
+
>>> df.select(last())
|
|
140
|
+
DataFrame[...]
|
|
141
|
+
"""
|
|
142
|
+
return by_index(-1, require_col_match=require_col_match)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
# --------------------------------------------------------------------------------
|
|
146
|
+
# DTYPE SECTION
|
|
147
|
+
# create main by_dtype function that is used for all dtype based column selection
|
|
148
|
+
# --------------------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def by_dtype(dtypes: type | Sequence[type], require_col_match: bool = True) -> DTypeSelector:
|
|
152
|
+
"""Select columns whose real Spark SQL type is (or is a subclass of) any of `dtypes`.
|
|
153
|
+
|
|
154
|
+
Parameters
|
|
155
|
+
----------
|
|
156
|
+
dtypes : type or sequence of type
|
|
157
|
+
One or more `pyspark.sql.types.DataType` subclasses to match, e.g.
|
|
158
|
+
``[T.IntegerType, T.StringType]``. A category base class (e.g.
|
|
159
|
+
``T.NumericType``) matches every concrete subclass of it too (see
|
|
160
|
+
`DTypeSelector`).
|
|
161
|
+
require_col_match : bool, default True
|
|
162
|
+
If `True` (default), resolving this selector against a dataframe
|
|
163
|
+
with zero matching columns raises `pyspark.errors.PySparkValueError`.
|
|
164
|
+
Set to `False` to opt out and allow a zero-column match instead.
|
|
165
|
+
|
|
166
|
+
Returns
|
|
167
|
+
-------
|
|
168
|
+
DTypeSelector
|
|
169
|
+
A selector matching every column whose real datatype is in `dtypes`,
|
|
170
|
+
composable with ``~ - & ^ |`` and chainable with arithmetic/spark
|
|
171
|
+
functions (e.g. ``.cast(...)``, ``.sum()``, ``+ 1``).
|
|
172
|
+
|
|
173
|
+
Examples
|
|
174
|
+
--------
|
|
175
|
+
>>> df.select(by_dtype([T.IntegerType, T.DoubleType]))
|
|
176
|
+
DataFrame[...]
|
|
177
|
+
>>> df.filter(by_dtype([T.IntegerType]) > 0)
|
|
178
|
+
DataFrame[...]
|
|
179
|
+
>>> df.select(by_dtype([T.BinaryType], require_col_match=False))
|
|
180
|
+
DataFrame[...]
|
|
181
|
+
"""
|
|
182
|
+
return DTypeSelector(dtypes, require_col_match=require_col_match)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# --------------------------------------------------------------------------------
|
|
186
|
+
# create string column selector from by_dtype function
|
|
187
|
+
# --------------------------------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def string(require_col_match: bool = True) -> DTypeSelector:
|
|
191
|
+
"""Select every `pyspark.sql.types.StringType` column.
|
|
192
|
+
|
|
193
|
+
Parameters
|
|
194
|
+
----------
|
|
195
|
+
require_col_match : bool, default True
|
|
196
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
197
|
+
zero-match error and allow no matching columns.
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
DTypeSelector
|
|
202
|
+
Equivalent to ``by_dtype([T.StringType])``.
|
|
203
|
+
|
|
204
|
+
Examples
|
|
205
|
+
--------
|
|
206
|
+
>>> df.select(string())
|
|
207
|
+
DataFrame[...]
|
|
208
|
+
"""
|
|
209
|
+
return by_dtype([T.StringType], require_col_match=require_col_match)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# --------------------------------------------------------------------------------
|
|
213
|
+
# create boolean column selector from by_dtype function
|
|
214
|
+
# --------------------------------------------------------------------------------
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def boolean(require_col_match: bool = True) -> DTypeSelector:
|
|
218
|
+
"""Select every `pyspark.sql.types.BooleanType` column.
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
require_col_match : bool, default True
|
|
223
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
224
|
+
zero-match error and allow no matching columns.
|
|
225
|
+
|
|
226
|
+
Returns
|
|
227
|
+
-------
|
|
228
|
+
DTypeSelector
|
|
229
|
+
Equivalent to ``by_dtype([T.BooleanType])``.
|
|
230
|
+
|
|
231
|
+
Examples
|
|
232
|
+
--------
|
|
233
|
+
>>> df.select(boolean())
|
|
234
|
+
DataFrame[...]
|
|
235
|
+
"""
|
|
236
|
+
return by_dtype([T.BooleanType], require_col_match=require_col_match)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
# --------------------------------------------------------------------------------
|
|
240
|
+
# create binary column selector from by_dtype function
|
|
241
|
+
# --------------------------------------------------------------------------------
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def binary(require_col_match: bool = True) -> DTypeSelector:
|
|
245
|
+
"""Select every `pyspark.sql.types.BinaryType` column.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
require_col_match : bool, default True
|
|
250
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
251
|
+
zero-match error and allow no matching columns.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
DTypeSelector
|
|
256
|
+
Equivalent to ``by_dtype([T.BinaryType])``.
|
|
257
|
+
|
|
258
|
+
Examples
|
|
259
|
+
--------
|
|
260
|
+
>>> df.select(binary())
|
|
261
|
+
DataFrame[...]
|
|
262
|
+
"""
|
|
263
|
+
return by_dtype([T.BinaryType], require_col_match=require_col_match)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
# --------------------------------------------------------------------------------
|
|
267
|
+
# create integer column selector from by_dtype function
|
|
268
|
+
# --------------------------------------------------------------------------------
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def integer(require_col_match: bool = True) -> DTypeSelector:
|
|
272
|
+
"""Select every fixed-width integer column.
|
|
273
|
+
|
|
274
|
+
Parameters
|
|
275
|
+
----------
|
|
276
|
+
require_col_match : bool, default True
|
|
277
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
278
|
+
zero-match error and allow no matching columns.
|
|
279
|
+
|
|
280
|
+
Returns
|
|
281
|
+
-------
|
|
282
|
+
DTypeSelector
|
|
283
|
+
Equivalent to ``by_dtype([T.IntegralType])`` -- matches
|
|
284
|
+
`ByteType`/`ShortType`/`IntegerType`/`LongType`, pyspark's real
|
|
285
|
+
integer type category.
|
|
286
|
+
|
|
287
|
+
Examples
|
|
288
|
+
--------
|
|
289
|
+
>>> df.select(integer())
|
|
290
|
+
DataFrame[...]
|
|
291
|
+
"""
|
|
292
|
+
return by_dtype([T.IntegralType], require_col_match=require_col_match)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
# --------------------------------------------------------------------------------
|
|
296
|
+
# create float column selector from by_dtype function
|
|
297
|
+
# --------------------------------------------------------------------------------
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def floats(require_col_match: bool = True) -> DTypeSelector:
|
|
301
|
+
"""Select every floating-point column (excluding `T.DecimalType`).
|
|
302
|
+
|
|
303
|
+
Parameters
|
|
304
|
+
----------
|
|
305
|
+
require_col_match : bool, default True
|
|
306
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
307
|
+
zero-match error and allow no matching columns.
|
|
308
|
+
|
|
309
|
+
Returns
|
|
310
|
+
-------
|
|
311
|
+
DTypeSelector
|
|
312
|
+
Equivalent to ``by_dtype([T.FloatType, T.DoubleType])``.
|
|
313
|
+
|
|
314
|
+
Examples
|
|
315
|
+
--------
|
|
316
|
+
>>> df.select(floats())
|
|
317
|
+
DataFrame[...]
|
|
318
|
+
"""
|
|
319
|
+
return by_dtype([T.FloatType, T.DoubleType], require_col_match=require_col_match)
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
# --------------------------------------------------------------------------------
|
|
323
|
+
# create numeric column selector from by_dtype function
|
|
324
|
+
# --------------------------------------------------------------------------------
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def numeric(require_col_match: bool = True) -> DTypeSelector:
|
|
328
|
+
"""Select every numeric column (integer, floating-point, or decimal).
|
|
329
|
+
|
|
330
|
+
Notes
|
|
331
|
+
-----
|
|
332
|
+
Unlike a plain dtype-string match, this uses pyspark's real
|
|
333
|
+
`T.NumericType` category, which includes `T.DecimalType` -- decimal
|
|
334
|
+
columns are matched here even though their dtype string is parametrized
|
|
335
|
+
per column (e.g. ``'decimal(10,2)'``).
|
|
336
|
+
|
|
337
|
+
Parameters
|
|
338
|
+
----------
|
|
339
|
+
require_col_match : bool, default True
|
|
340
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
341
|
+
zero-match error and allow no matching columns.
|
|
342
|
+
|
|
343
|
+
Returns
|
|
344
|
+
-------
|
|
345
|
+
DTypeSelector
|
|
346
|
+
Equivalent to ``by_dtype([T.NumericType])``.
|
|
347
|
+
|
|
348
|
+
Examples
|
|
349
|
+
--------
|
|
350
|
+
>>> df.select(numeric())
|
|
351
|
+
DataFrame[...]
|
|
352
|
+
"""
|
|
353
|
+
return by_dtype([T.NumericType], require_col_match=require_col_match)
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
# --------------------------------------------------------------------------------
|
|
357
|
+
# create date column selector from by_dtype function
|
|
358
|
+
# --------------------------------------------------------------------------------
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def date(require_col_match: bool = True) -> DTypeSelector:
|
|
362
|
+
"""Select every `pyspark.sql.types.DateType` column.
|
|
363
|
+
|
|
364
|
+
Parameters
|
|
365
|
+
----------
|
|
366
|
+
require_col_match : bool, default True
|
|
367
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
368
|
+
zero-match error and allow no matching columns.
|
|
369
|
+
|
|
370
|
+
Returns
|
|
371
|
+
-------
|
|
372
|
+
DTypeSelector
|
|
373
|
+
Equivalent to ``by_dtype([T.DateType])``.
|
|
374
|
+
|
|
375
|
+
Examples
|
|
376
|
+
--------
|
|
377
|
+
>>> df.select(date())
|
|
378
|
+
DataFrame[...]
|
|
379
|
+
"""
|
|
380
|
+
return by_dtype([T.DateType], require_col_match=require_col_match)
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
# --------------------------------------------------------------------------------
|
|
384
|
+
# create datetime column selector from by_dtype function
|
|
385
|
+
# --------------------------------------------------------------------------------
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def datetime_(require_col_match: bool = True) -> DTypeSelector:
|
|
389
|
+
"""Select every timestamp column (`T.TimestampType` and, if available, `T.TimestampNTZType`).
|
|
390
|
+
|
|
391
|
+
Parameters
|
|
392
|
+
----------
|
|
393
|
+
require_col_match : bool, default True
|
|
394
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
395
|
+
zero-match error and allow no matching columns.
|
|
396
|
+
|
|
397
|
+
Returns
|
|
398
|
+
-------
|
|
399
|
+
DTypeSelector
|
|
400
|
+
Equivalent to ``by_dtype([T.TimestampType, T.TimestampNTZType])`` on
|
|
401
|
+
Spark versions where `T.TimestampNTZType` exists, otherwise just
|
|
402
|
+
``by_dtype([T.TimestampType])``.
|
|
403
|
+
|
|
404
|
+
Examples
|
|
405
|
+
--------
|
|
406
|
+
>>> df.select(datetime_())
|
|
407
|
+
DataFrame[...]
|
|
408
|
+
"""
|
|
409
|
+
return by_dtype(list(_TIMESTAMP_TYPES), require_col_match=require_col_match)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# --------------------------------------------------------------------------------
|
|
413
|
+
# create temporal column selector from by_dtype function
|
|
414
|
+
# --------------------------------------------------------------------------------
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def temporal(require_col_match: bool = True) -> DTypeSelector:
|
|
418
|
+
"""Select every date or timestamp column.
|
|
419
|
+
|
|
420
|
+
pyspark has no single common base class covering `T.DateType` and every
|
|
421
|
+
timestamp type, so this is a self-defined grouping rather than one
|
|
422
|
+
category class.
|
|
423
|
+
|
|
424
|
+
Parameters
|
|
425
|
+
----------
|
|
426
|
+
require_col_match : bool, default True
|
|
427
|
+
Forwarded to `by_dtype`. Set to `False` to opt out of the
|
|
428
|
+
zero-match error and allow no matching columns.
|
|
429
|
+
|
|
430
|
+
Returns
|
|
431
|
+
-------
|
|
432
|
+
DTypeSelector
|
|
433
|
+
Equivalent to ``by_dtype([T.DateType, T.TimestampType, T.TimestampNTZType])``
|
|
434
|
+
on Spark versions where `T.TimestampNTZType` exists, otherwise
|
|
435
|
+
``by_dtype([T.DateType, T.TimestampType])``.
|
|
436
|
+
|
|
437
|
+
Examples
|
|
438
|
+
--------
|
|
439
|
+
>>> df.select(temporal())
|
|
440
|
+
DataFrame[...]
|
|
441
|
+
"""
|
|
442
|
+
return by_dtype([T.DateType, *_TIMESTAMP_TYPES], require_col_match=require_col_match)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
# --------------------------------------------------------------------------------
|
|
446
|
+
# COLUMN NAME BASED SELECTORS SECTION
|
|
447
|
+
# create matches function used for all COLUMN NAME BASED SELECTORS based column selection
|
|
448
|
+
# entirely done using regular expressions
|
|
449
|
+
# --------------------------------------------------------------------------------
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def matches(pattern: str, require_col_match: bool = True) -> RegexSelector:
|
|
453
|
+
"""Select columns whose name matches a regex pattern.
|
|
454
|
+
|
|
455
|
+
Parameters
|
|
456
|
+
----------
|
|
457
|
+
pattern : str
|
|
458
|
+
A regular expression, matched against each column name via
|
|
459
|
+
`re.search`.
|
|
460
|
+
require_col_match : bool, default True
|
|
461
|
+
If `True` (default), resolving this selector against a dataframe
|
|
462
|
+
with zero matching columns raises `pyspark.errors.PySparkValueError`.
|
|
463
|
+
Set to `False` to opt out and allow a zero-column match instead.
|
|
464
|
+
|
|
465
|
+
Returns
|
|
466
|
+
-------
|
|
467
|
+
RegexSelector
|
|
468
|
+
A selector matching every column whose name matches `pattern`,
|
|
469
|
+
composable with ``~ - & ^ |`` and chainable with arithmetic/spark
|
|
470
|
+
functions.
|
|
471
|
+
|
|
472
|
+
Examples
|
|
473
|
+
--------
|
|
474
|
+
>>> df.select(matches(r"_id$"))
|
|
475
|
+
DataFrame[...]
|
|
476
|
+
>>> df.select(matches(r"_id$").upper())
|
|
477
|
+
DataFrame[...]
|
|
478
|
+
"""
|
|
479
|
+
return RegexSelector(pattern, require_col_match=require_col_match)
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
# --------------------------------------------------------------------------------
|
|
483
|
+
# create starts_with column selector from matches function
|
|
484
|
+
# --------------------------------------------------------------------------------
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def starts_with(*prefixes: str, require_col_match: bool = True) -> RegexSelector:
|
|
488
|
+
"""Select columns whose name starts with any of `prefixes`.
|
|
489
|
+
|
|
490
|
+
Parameters
|
|
491
|
+
----------
|
|
492
|
+
*prefixes : str
|
|
493
|
+
One or more literal prefixes to match against the start of each
|
|
494
|
+
column name.
|
|
495
|
+
require_col_match : bool, default True
|
|
496
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
497
|
+
zero-match error and allow no matching columns.
|
|
498
|
+
|
|
499
|
+
Returns
|
|
500
|
+
-------
|
|
501
|
+
RegexSelector
|
|
502
|
+
Equivalent to ``matches(r"^(prefix1|prefix2|...)")``.
|
|
503
|
+
|
|
504
|
+
Examples
|
|
505
|
+
--------
|
|
506
|
+
>>> df.select(starts_with('project_'))
|
|
507
|
+
DataFrame[...]
|
|
508
|
+
"""
|
|
509
|
+
return matches(r"^(" + "|".join(re.escape(p) for p in prefixes) + r")", require_col_match=require_col_match)
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
# --------------------------------------------------------------------------------
|
|
513
|
+
# create ends_with column selector from matches function
|
|
514
|
+
# --------------------------------------------------------------------------------
|
|
515
|
+
|
|
516
|
+
|
|
517
|
+
def ends_with(*suffixes: str, require_col_match: bool = True) -> RegexSelector:
|
|
518
|
+
"""Select columns whose name ends with any of `suffixes`.
|
|
519
|
+
|
|
520
|
+
Parameters
|
|
521
|
+
----------
|
|
522
|
+
*suffixes : str
|
|
523
|
+
One or more literal suffixes to match against the end of each
|
|
524
|
+
column name.
|
|
525
|
+
require_col_match : bool, default True
|
|
526
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
527
|
+
zero-match error and allow no matching columns.
|
|
528
|
+
|
|
529
|
+
Returns
|
|
530
|
+
-------
|
|
531
|
+
RegexSelector
|
|
532
|
+
Equivalent to ``matches(r"(suffix1|suffix2|...)$")``.
|
|
533
|
+
|
|
534
|
+
Examples
|
|
535
|
+
--------
|
|
536
|
+
>>> df.select(ends_with('_id'))
|
|
537
|
+
DataFrame[...]
|
|
538
|
+
"""
|
|
539
|
+
return matches(r"(" + "|".join(re.escape(s) for s in suffixes) + r")$", require_col_match=require_col_match)
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
# --------------------------------------------------------------------------------
|
|
543
|
+
# create contains column selector from matches function
|
|
544
|
+
# --------------------------------------------------------------------------------
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def contains(*substrings: str, require_col_match: bool = True) -> RegexSelector:
|
|
548
|
+
"""Select columns whose name contains any of `substrings`.
|
|
549
|
+
|
|
550
|
+
Parameters
|
|
551
|
+
----------
|
|
552
|
+
*substrings : str
|
|
553
|
+
One or more literal substrings to search for anywhere in each
|
|
554
|
+
column name.
|
|
555
|
+
require_col_match : bool, default True
|
|
556
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
557
|
+
zero-match error and allow no matching columns.
|
|
558
|
+
|
|
559
|
+
Returns
|
|
560
|
+
-------
|
|
561
|
+
RegexSelector
|
|
562
|
+
Equivalent to ``matches(r"(substring1|substring2|...)")``.
|
|
563
|
+
|
|
564
|
+
Examples
|
|
565
|
+
--------
|
|
566
|
+
>>> df.select(contains('project'))
|
|
567
|
+
DataFrame[...]
|
|
568
|
+
"""
|
|
569
|
+
return matches("(" + "|".join(re.escape(s) for s in substrings) + ")", require_col_match=require_col_match)
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
# --------------------------------------------------------------------------------
|
|
573
|
+
# create by_name column selector from matches function
|
|
574
|
+
# --------------------------------------------------------------------------------
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
def by_name(*names: str, require_col_match: bool = True) -> RegexSelector:
|
|
578
|
+
"""Select columns whose name exactly matches any of `names`.
|
|
579
|
+
|
|
580
|
+
Parameters
|
|
581
|
+
----------
|
|
582
|
+
*names : str
|
|
583
|
+
One or more exact column names to select.
|
|
584
|
+
require_col_match : bool, default True
|
|
585
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
586
|
+
zero-match error and allow no matching columns.
|
|
587
|
+
|
|
588
|
+
Returns
|
|
589
|
+
-------
|
|
590
|
+
RegexSelector
|
|
591
|
+
Equivalent to ``matches(r"^(name1|name2|...)$")``.
|
|
592
|
+
|
|
593
|
+
Examples
|
|
594
|
+
--------
|
|
595
|
+
>>> df.select(by_name('string_col', 'data_column_5'))
|
|
596
|
+
DataFrame[...]
|
|
597
|
+
"""
|
|
598
|
+
return matches(r"^(" + "|".join(re.escape(n) for n in names) + r")$", require_col_match=require_col_match)
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
# --------------------------------------------------------------------------------
|
|
602
|
+
# create exclude column selector from matches function
|
|
603
|
+
# --------------------------------------------------------------------------------
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def exclude(*names: str, require_col_match: bool = True) -> BaseSelector:
|
|
607
|
+
"""Select every column EXCEPT `names`.
|
|
608
|
+
|
|
609
|
+
Parameters
|
|
610
|
+
----------
|
|
611
|
+
*names : str
|
|
612
|
+
One or more exact column names to exclude.
|
|
613
|
+
require_col_match : bool, default True
|
|
614
|
+
Forwarded to both `all` and `by_name`. Set to `False` to opt out of
|
|
615
|
+
the zero-match error and allow no matching columns (e.g. when
|
|
616
|
+
excluding every column on the dataframe).
|
|
617
|
+
|
|
618
|
+
Returns
|
|
619
|
+
-------
|
|
620
|
+
BaseSelector
|
|
621
|
+
Equivalent to ``all() - by_name(*names)``.
|
|
622
|
+
|
|
623
|
+
Examples
|
|
624
|
+
--------
|
|
625
|
+
>>> df.select(exclude('string_col'))
|
|
626
|
+
DataFrame[...]
|
|
627
|
+
"""
|
|
628
|
+
return cast(
|
|
629
|
+
BaseSelector,
|
|
630
|
+
all(require_col_match=require_col_match) - by_name(*names, require_col_match=require_col_match),
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
# --------------------------------------------------------------------------------
|
|
635
|
+
# create alphabetical column selector from matches function
|
|
636
|
+
# --------------------------------------------------------------------------------
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
def alpha(require_col_match: bool = True) -> RegexSelector:
|
|
640
|
+
"""Select columns whose name consists only of alphabetic characters.
|
|
641
|
+
|
|
642
|
+
Parameters
|
|
643
|
+
----------
|
|
644
|
+
require_col_match : bool, default True
|
|
645
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
646
|
+
zero-match error and allow no matching columns.
|
|
647
|
+
|
|
648
|
+
Returns
|
|
649
|
+
-------
|
|
650
|
+
RegexSelector
|
|
651
|
+
Equivalent to ``matches(r"^[a-zA-Z]+$")``.
|
|
652
|
+
|
|
653
|
+
Examples
|
|
654
|
+
--------
|
|
655
|
+
>>> df.select(alpha())
|
|
656
|
+
DataFrame[...]
|
|
657
|
+
"""
|
|
658
|
+
return matches(r"^[a-zA-Z]+$", require_col_match=require_col_match)
|
|
659
|
+
|
|
660
|
+
|
|
661
|
+
# --------------------------------------------------------------------------------
|
|
662
|
+
# create alphanumeric column selector from matches function
|
|
663
|
+
# --------------------------------------------------------------------------------
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
def alphanumeric(require_col_match: bool = True) -> RegexSelector:
|
|
667
|
+
"""Select columns whose name consists only of letters and/or digits.
|
|
668
|
+
|
|
669
|
+
Parameters
|
|
670
|
+
----------
|
|
671
|
+
require_col_match : bool, default True
|
|
672
|
+
Forwarded to `matches`. Set to `False` to opt out of the
|
|
673
|
+
zero-match error and allow no matching columns.
|
|
674
|
+
|
|
675
|
+
Returns
|
|
676
|
+
-------
|
|
677
|
+
RegexSelector
|
|
678
|
+
Equivalent to ``matches(r"^[a-zA-Z0-9]+$")``.
|
|
679
|
+
|
|
680
|
+
Examples
|
|
681
|
+
--------
|
|
682
|
+
>>> df.select(alphanumeric())
|
|
683
|
+
DataFrame[...]
|
|
684
|
+
"""
|
|
685
|
+
return matches(r"^[a-zA-Z0-9]+$", require_col_match=require_col_match)
|
|
686
|
+
|
|
687
|
+
|
|
688
|
+
# --------------------------------------------------------------------------------
|
|
689
|
+
# create all column selector from matches function
|
|
690
|
+
# --------------------------------------------------------------------------------
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
def all(require_col_match: bool = True) -> RegexSelector:
|
|
694
|
+
"""Select every column.
|
|
695
|
+
|
|
696
|
+
Parameters
|
|
697
|
+
----------
|
|
698
|
+
require_col_match : bool, default True
|
|
699
|
+
Whether resolving raises `pyspark.errors.PySparkValueError` when the
|
|
700
|
+
dataframe has zero columns. Forwarded to `RegexSelector`.
|
|
701
|
+
|
|
702
|
+
Returns
|
|
703
|
+
-------
|
|
704
|
+
RegexSelector
|
|
705
|
+
A selector matching every column name (built from a match-everything
|
|
706
|
+
regex, since `IndexSelector` has no "all of them" spelling without
|
|
707
|
+
already knowing the dataframe's column count).
|
|
708
|
+
|
|
709
|
+
Examples
|
|
710
|
+
--------
|
|
711
|
+
>>> df.select(all())
|
|
712
|
+
DataFrame[...]
|
|
713
|
+
"""
|
|
714
|
+
return RegexSelector(r".*", require_col_match=require_col_match)
|
|
715
|
+
|
|
716
|
+
|
|
717
|
+
# --------------------------------------------------------------------------------
|
|
718
|
+
# create boolean to detect column selectors.
|
|
719
|
+
# --------------------------------------------------------------------------------
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
def is_selector(x: Any) -> bool:
|
|
723
|
+
"""Return whether `x` is one of this framework's column selector objects.
|
|
724
|
+
|
|
725
|
+
Parameters
|
|
726
|
+
----------
|
|
727
|
+
x : Any
|
|
728
|
+
The value to check -- e.g. the result of `by_dtype`, `by_index`,
|
|
729
|
+
`matches`, or any of those combined with ``~ - & ^ |``.
|
|
730
|
+
|
|
731
|
+
Returns
|
|
732
|
+
-------
|
|
733
|
+
bool
|
|
734
|
+
`True` if `x` is a `BaseSelector` instance (or subclass instance),
|
|
735
|
+
`False` for anything else (plain column names, `pyspark.sql.Column`
|
|
736
|
+
results, literals, etc).
|
|
737
|
+
|
|
738
|
+
Examples
|
|
739
|
+
--------
|
|
740
|
+
>>> is_selector(by_dtype([T.IntegerType]))
|
|
741
|
+
True
|
|
742
|
+
>>> is_selector('string_col')
|
|
743
|
+
False
|
|
744
|
+
"""
|
|
745
|
+
return isinstance(x, BaseSelector)
|