hossam 0.4.4__py3-none-any.whl → 0.4.6__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.
hossam/hs_prep.py CHANGED
@@ -5,6 +5,7 @@
5
5
  import joblib
6
6
  import numpy as np
7
7
  from itertools import combinations
8
+ from typing import Any
8
9
 
9
10
  import pandas as pd
10
11
  import jenkspy
@@ -19,7 +20,7 @@ from .hs_util import pretty_table
19
20
  # 연속형 변수를 표준정규화(Z-score)로 변환한다
20
21
  # ===================================================================
21
22
  def standard_scaler(
22
- data: any, yname: str | None = None, save_path: str | None = None, load_path: str | None = None
23
+ data: Any, yname: str | None = None, save_path: str | None = None, load_path: str | None = None
23
24
  ) -> DataFrame:
24
25
  """연속형 변수에 대해 Standard Scaling을 수행한다.
25
26
 
@@ -54,7 +55,7 @@ def standard_scaler(
54
55
  sdata = scaler.transform(arr) if load_path else scaler.fit_transform(arr)
55
56
  if save_path:
56
57
  joblib.dump(value=scaler, filename=save_path)
57
- return sdata
58
+ return sdata # type: ignore
58
59
 
59
60
  df = data.copy()
60
61
 
@@ -90,7 +91,7 @@ def standard_scaler(
90
91
  # 연속형 변수를 0부터 1 사이의 값으로 정규화한다
91
92
  # ===================================================================
92
93
  def minmax_scaler(
93
- data: any, yname: str | None = None, save_path: str | None = None, load_path: str | None = None
94
+ data: Any, yname: str | None = None, save_path: str | None = None, load_path: str | None = None
94
95
  ) -> DataFrame:
95
96
  """연속형 변수에 대해 MinMax Scaling을 수행한다.
96
97
 
@@ -123,7 +124,7 @@ def minmax_scaler(
123
124
  sdata = scaler.transform(arr) if load_path else scaler.fit_transform(arr)
124
125
  if save_path:
125
126
  joblib.dump(scaler, save_path)
126
- return sdata
127
+ return sdata # type: ignore
127
128
 
128
129
  df = data.copy()
129
130
 
@@ -158,7 +159,7 @@ def minmax_scaler(
158
159
  # ===================================================================
159
160
  # 지정된 컬럼들을 범주형 데이터로 설정한다
160
161
  # ===================================================================
161
- def set_category(data: DataFrame, *args: str, columns: list = None) -> DataFrame:
162
+ def set_category(data: DataFrame, *args: str, columns: list | None = None) -> DataFrame:
162
163
  """카테고리 데이터를 설정한다.
163
164
 
164
165
  Args:
@@ -173,7 +174,7 @@ def set_category(data: DataFrame, *args: str, columns: list = None) -> DataFrame
173
174
  if columns is not None:
174
175
  if args:
175
176
  raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
176
- args = columns
177
+ args = columns # type: ignore
177
178
 
178
179
  df = data.copy()
179
180
 
@@ -226,7 +227,7 @@ def unmelt(
226
227
  # ===================================================================
227
228
  # 지정된 변수의 이상치 테이블로 반환한다
228
229
  # ===================================================================
229
- def outlier_table(data: DataFrame, *fields: str, columns: list = None) -> DataFrame:
230
+ def outlier_table(data: DataFrame, *fields: str, columns: list | None = None) -> DataFrame:
230
231
  """수치형 컬럼에 대한 사분위수 및 IQR 기반 이상치 경계를 계산한다.
231
232
 
232
233
  전달된 `fields`가 없으면 데이터프레임의 모든 수치형 컬럼을 대상으로 한다.
@@ -246,7 +247,7 @@ def outlier_table(data: DataFrame, *fields: str, columns: list = None) -> DataFr
246
247
  """
247
248
  # columns 인자가 있으면 args보다 우선한다.
248
249
  if columns is not None:
249
- if args:
250
+ if args: # type: ignore
250
251
  raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
251
252
  args = columns
252
253
 
@@ -286,7 +287,7 @@ def outlier_table(data: DataFrame, *fields: str, columns: list = None) -> DataFr
286
287
  # ===================================================================
287
288
  # 이상치를 대체값(NaN, 0) 또는 중앙값으로 교체한다
288
289
  # ===================================================================
289
- def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns: list = None) -> DataFrame:
290
+ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns: list | None = None) -> DataFrame:
290
291
  """이상치 경계값을 넘어가는 데이터를 경계값으로 대체한다.
291
292
 
292
293
  Args:
@@ -305,7 +306,7 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns
305
306
  """
306
307
  # columns 인자가 있으면 args보다 우선한다.
307
308
  if columns is not None:
308
- if args:
309
+ if args: # type: ignore
309
310
  raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
310
311
  args = columns
311
312
 
@@ -354,7 +355,7 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns
354
355
  # ===================================================================
355
356
  # 중빈 이상치를 제거한 연처리된 데이터프레임을 반환한다
356
357
  # ===================================================================
357
- def drop_outliner(data: DataFrame, *fields: str, columns: list = None) -> DataFrame:
358
+ def drop_outliner(data: DataFrame, *fields: str, columns: list | None = None) -> DataFrame:
358
359
  """이상치를 결측치로 변환한 후 모두 삭제한다.
359
360
 
360
361
  Args:
@@ -367,7 +368,7 @@ def drop_outliner(data: DataFrame, *fields: str, columns: list = None) -> DataFr
367
368
  """
368
369
  # columns 인자가 있으면 args보다 우선한다.
369
370
  if columns is not None:
370
- if args:
371
+ if args: # type: ignore
371
372
  raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
372
373
  args = columns
373
374
 
@@ -378,7 +379,7 @@ def drop_outliner(data: DataFrame, *fields: str, columns: list = None) -> DataFr
378
379
  # ===================================================================
379
380
  # 범주 변수를 더미 변수(One-Hot 인코딩)로 변환한다
380
381
  # ===================================================================
381
- def get_dummies(data: DataFrame, *args: str, columns: list = None, drop_first: bool = True, dtype: str = "int") -> DataFrame:
382
+ def get_dummies(data: DataFrame, *args: str, columns: list | None = None, drop_first: bool = True, dtype: str = "int") -> DataFrame:
382
383
  """명목형 변수를 더미 변수로 변환한다.
383
384
 
384
385
  컬럼명을 지정하면 그 컬럼들만 더미 변수로 변환하고,
@@ -409,7 +410,7 @@ def get_dummies(data: DataFrame, *args: str, columns: list = None, drop_first: b
409
410
  if columns is not None:
410
411
  if args:
411
412
  raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
412
- args = columns
413
+ args = columns # type: ignore
413
414
 
414
415
  if not args:
415
416
  # args가 없으면 숫자 타입이 아닌 모든 컬럼 자동 선택
@@ -417,13 +418,13 @@ def get_dummies(data: DataFrame, *args: str, columns: list = None, drop_first: b
417
418
  for f in data.columns:
418
419
  if not pd.api.types.is_numeric_dtype(data[f]):
419
420
  cols_to_convert.append(f)
420
- args = cols_to_convert
421
+ args = cols_to_convert # type: ignore
421
422
  else:
422
423
  # args가 있으면 그 컬럼들만 사용 (존재 여부 확인)
423
- args = [c for c in args if c in data.columns]
424
+ args = [c for c in args if c in data.columns] # type: ignore
424
425
 
425
426
  # pandas.get_dummies 사용 (재귀 문제 없음)
426
- return pd.get_dummies(data, columns=args, drop_first=drop_first, dtype=dtype) if args else data.copy()
427
+ return pd.get_dummies(data, columns=args, drop_first=drop_first, dtype=dtype) if args else data.copy() # type: ignore
427
428
 
428
429
 
429
430
  # ===================================================================
@@ -630,7 +631,7 @@ def bin_continuous(
630
631
  if apply_labels:
631
632
  # 숫자 인덱스 사용 (0, 1, 2, ...)
632
633
  numeric_labels = list(range(len(edges) - 1))
633
- df[new_col] = pd.cut(series, bins=edges, labels=numeric_labels, include_lowest=True, ordered=False)
634
+ df[new_col] = pd.cut(series, bins=edges, labels=numeric_labels, include_lowest=True, ordered=False) # type: ignore
634
635
  else:
635
636
  # 문자 레이블 적용
636
637
  if labels is None:
@@ -645,9 +646,9 @@ def bin_continuous(
645
646
  except:
646
647
  pass
647
648
  auto_labels.append(f"{left}~{right}")
648
- df[new_col] = pd.cut(series, bins=edges, labels=auto_labels, include_lowest=True, ordered=False)
649
+ df[new_col] = pd.cut(series, bins=edges, labels=auto_labels, include_lowest=True, ordered=False) # type: ignore
649
650
  else:
650
- df[new_col] = pd.cut(series, bins=edges, labels=labels, include_lowest=True, ordered=False)
651
+ df[new_col] = pd.cut(series, bins=edges, labels=labels, include_lowest=True, ordered=False) # type: ignore
651
652
 
652
653
  df[new_col] = df[new_col].astype("category")
653
654
  return df
@@ -671,26 +672,24 @@ def bin_continuous(
671
672
  n_bins = len(edges) - 1
672
673
  if apply_labels:
673
674
  numeric_labels = list(range(n_bins))
674
- df[new_col] = pd.cut(series, bins=edges, labels=numeric_labels, include_lowest=True, ordered=False)
675
+ df[new_col] = pd.cut(series, bins=edges, labels=numeric_labels, include_lowest=True, ordered=False) # type: ignore
675
676
  else:
676
677
  if labels is None:
677
678
  position_labels = [f"Q{i+1}" for i in range(n_bins)]
678
- df[new_col] = pd.cut(
679
- series, bins=edges, labels=position_labels, include_lowest=True, ordered=False
680
- )
679
+ df[new_col] = pd.cut(series, bins=edges, labels=position_labels, include_lowest=True, ordered=False) # type: ignore
681
680
  else:
682
- df[new_col] = pd.cut(series, bins=edges, labels=labels, include_lowest=True, ordered=False)
681
+ df[new_col] = pd.cut(series, bins=edges, labels=labels, include_lowest=True, ordered=False) # type: ignore
683
682
  df[new_col] = df[new_col].astype("category")
684
683
  return df
685
684
 
686
685
  # 자연 구간화 (Jenks) - 의존성 없으면 분위수로 폴백
687
686
  if method_key in {"natural_breaks", "natural", "jenks"}:
688
687
  k = bins if isinstance(bins, int) and bins > 1 else 5
689
- series_nonnull = series.dropna()
688
+ series_nonnull = series.dropna() # type: ignore
690
689
  k = min(k, max(2, series_nonnull.nunique()))
691
690
  edges = None
692
691
  try:
693
- edges = jenkspy.jenks_breaks(series_nonnull.to_list(), nb_class=k)
692
+ edges = jenkspy.jenks_breaks(series_nonnull.to_list(), nb_class=k) # type: ignore
694
693
  edges[0] = -np.inf
695
694
  edges[-1] = np.inf
696
695
  except Exception:
@@ -730,7 +729,7 @@ def bin_continuous(
730
729
  if apply_labels:
731
730
  # 숫자 인덱스 사용
732
731
  numeric_labels = list(range(len(cut_edges) - 1))
733
- df[new_col] = pd.cut(series, bins=cut_edges, labels=numeric_labels, include_lowest=True, ordered=False)
732
+ df[new_col] = pd.cut(series, bins=cut_edges, labels=numeric_labels, include_lowest=True, ordered=False) # type: ignore
734
733
  else:
735
734
  if labels is None:
736
735
  auto_labels = []
@@ -744,9 +743,9 @@ def bin_continuous(
744
743
  except:
745
744
  pass
746
745
  auto_labels.append(f"{left}~{right}")
747
- df[new_col] = pd.cut(series, bins=cut_edges, labels=auto_labels, include_lowest=True, ordered=False)
746
+ df[new_col] = pd.cut(series, bins=cut_edges, labels=auto_labels, include_lowest=True, ordered=False) # type: ignore
748
747
  else:
749
- df[new_col] = pd.cut(series, bins=cut_edges, labels=labels, include_lowest=True, ordered=False)
748
+ df[new_col] = pd.cut(series, bins=cut_edges, labels=labels, include_lowest=True, ordered=False) # type: ignore
750
749
  df[new_col] = df[new_col].astype("category")
751
750
  return df
752
751
 
@@ -765,7 +764,7 @@ def bin_continuous(
765
764
  # ===================================================================
766
765
  # 지정된 변수에 로그 먼저 변환을 적용한다
767
766
  # ===================================================================
768
- def log_transform(data: DataFrame, *fields: str) -> DataFrame:
767
+ def log_transform(data: DataFrame, *fields: str, columns: list | None = None) -> DataFrame:
769
768
  """수치형 변수에 대해 로그 변환을 수행한다.
770
769
 
771
770
  자연로그(ln)를 사용하여 변환하며, 0 또는 음수 값이 있을 경우
@@ -774,6 +773,7 @@ def log_transform(data: DataFrame, *fields: str) -> DataFrame:
774
773
  Args:
775
774
  data (DataFrame): 변환할 데이터프레임.
776
775
  *fields (str): 변환할 컬럼명 목록. 지정하지 않으면 모든 수치형 컬럼을 처리.
776
+ columns (list, optional): 변환할 컬럼명 목록. fields와 중복 사용 불가.
777
777
 
778
778
  Returns:
779
779
  DataFrame: 로그 변환된 데이터프레임.
@@ -800,6 +800,11 @@ def log_transform(data: DataFrame, *fields: str) -> DataFrame:
800
800
  """
801
801
  df = data.copy()
802
802
 
803
+ if columns is not None:
804
+ if fields:
805
+ raise ValueError("fields와 columns 인자는 중복 사용할 수 없습니다.")
806
+ fields = columns # type: ignore
807
+
803
808
  # 대상 컬럼 결정
804
809
  if not fields:
805
810
  # 모든 수치형 컬럼 선택