dycw-utilities 0.159.6__py3-none-any.whl → 0.159.8__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.159.6
3
+ Version: 0.159.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=HU7fB_QysxkWUAfvaBlQ9lefAJoPmcPYawkPYCd-v-M,60
1
+ utilities/__init__.py,sha256=ZNV6cnMhMqb35heJ2XDn7MrYezCm7WhHn0JLWgxfK3c,60
2
2
  utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
3
3
  utilities/asyncio.py,sha256=PUedzQ5deqlSECQ33sam9cRzI9TnygHz3FdOqWJWPTM,15288
4
4
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
@@ -45,7 +45,7 @@ utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
45
45
  utilities/pathlib.py,sha256=qGuU8XPmdgGpy8tOMUgelfXx3kxI8h9IaV3TI_06QGE,8428
46
46
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
47
47
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
48
- utilities/polars.py,sha256=QTHk58M2dwIOCSR1JYttlrblUAw8Ihn7M8gAH4CtrGU,79542
48
+ utilities/polars.py,sha256=aDICWXSOP8F1P40kS3C7vIUY9RDVceOEdhDxYBWOv_8,80518
49
49
  utilities/polars_ols.py,sha256=Uc9V5kvlWZ5cU93lKZ-cfAKdVFFw81tqwLW9PxtUvMs,5618
50
50
  utilities/postgres.py,sha256=ynCTTaF-bVEOSW-KEAR-dlLh_hYjeVVjm__-4pEU8Zk,12269
51
51
  utilities/pottery.py,sha256=ggMN72Y7wx7Js8VN6eyNyodpm8TIYqZHGghkDPXIVWk,3949
@@ -87,8 +87,8 @@ utilities/zoneinfo.py,sha256=FBMcUQ4662Aq8SsuCL1OAhDQiyANmVjtb-C30DRrWoE,1966
87
87
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
88
88
  utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
89
89
  utilities/pytest_plugins/pytest_regressions.py,sha256=9v8kAXDM2ycIXJBimoiF4EgrwbUvxTycFWJiGR_GHhM,1466
90
- dycw_utilities-0.159.6.dist-info/METADATA,sha256=3LSln5-gxGAVHIOOes3Y_iplEd9Knl_UTtWoFkpCXpo,1643
91
- dycw_utilities-0.159.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
- dycw_utilities-0.159.6.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
93
- dycw_utilities-0.159.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.159.6.dist-info/RECORD,,
90
+ dycw_utilities-0.159.8.dist-info/METADATA,sha256=m2wmC4GlUq04TCY6GANKluJqCEl9MLw8XruIEQhM8Ew,1643
91
+ dycw_utilities-0.159.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
92
+ dycw_utilities-0.159.8.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
93
+ dycw_utilities-0.159.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.159.8.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.159.6"
3
+ __version__ = "0.159.8"
utilities/polars.py CHANGED
@@ -2421,8 +2421,16 @@ def round_to_float(
2421
2421
 
2422
2422
 
2423
2423
  def _round_to_float_one(df: DataFrame, /) -> DataFrame:
2424
- decimals: int = df["_decimals"].unique().item()
2425
- return df.with_columns(col(df.columns[1]).round(decimals=decimals))
2424
+ decimals: int | None = df["_decimals"].unique().item()
2425
+ name = df.columns[1]
2426
+ match decimals:
2427
+ case int():
2428
+ expr = col(name).round(decimals=decimals)
2429
+ case None:
2430
+ expr = lit(None, dtype=Float64).alias(name)
2431
+ case never:
2432
+ assert_never(never)
2433
+ return df.with_columns(expr)
2426
2434
 
2427
2435
 
2428
2436
  @dataclass(kw_only=True, slots=True)
@@ -2438,6 +2446,31 @@ class RoundToFloatError(Exception):
2438
2446
  ##
2439
2447
 
2440
2448
 
2449
+ def select_exact(
2450
+ df: DataFrame, /, *columns: IntoExprColumn, drop: MaybeIterable[str] | None = None
2451
+ ) -> DataFrame:
2452
+ """Select an exact set of columns from a DataFrame."""
2453
+ names = [get_expr_name(df, c) for c in columns]
2454
+ drop = set() if drop is None else set(always_iterable(drop))
2455
+ union = set(names) | drop
2456
+ extra = [c for c in df.columns if c not in union]
2457
+ if len(extra) >= 1:
2458
+ raise SelectExactError(columns=extra)
2459
+ return df.select(*columns)
2460
+
2461
+
2462
+ @dataclass(kw_only=True, slots=True)
2463
+ class SelectExactError(Exception):
2464
+ columns: list[str]
2465
+
2466
+ @override
2467
+ def __str__(self) -> str:
2468
+ return f"All columns must be selected; got {get_repr(self.columns)} remaining"
2469
+
2470
+
2471
+ ##
2472
+
2473
+
2441
2474
  def set_first_row_as_columns(df: DataFrame, /) -> DataFrame:
2442
2475
  """Set the first row of a DataFrame as its columns."""
2443
2476
  try:
@@ -2646,6 +2679,7 @@ __all__ = [
2646
2679
  "OneColumnError",
2647
2680
  "OneColumnNonUniqueError",
2648
2681
  "RoundToFloatError",
2682
+ "SelectExactError",
2649
2683
  "SetFirstRowAsColumnsError",
2650
2684
  "TimePeriodDType",
2651
2685
  "acf",
@@ -2701,6 +2735,7 @@ __all__ = [
2701
2735
  "read_series",
2702
2736
  "replace_time_zone",
2703
2737
  "round_to_float",
2738
+ "select_exact",
2704
2739
  "serialize_dataframe",
2705
2740
  "set_first_row_as_columns",
2706
2741
  "struct_dtype",