hossam 0.4.3__py3-none-any.whl → 0.4.5__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,16 +159,23 @@ def minmax_scaler(
158
159
  # ===================================================================
159
160
  # 지정된 컬럼들을 범주형 데이터로 설정한다
160
161
  # ===================================================================
161
- def set_category(data: DataFrame, *args: str) -> DataFrame:
162
+ def set_category(data: DataFrame, *args: str, columns: list | None = None) -> DataFrame:
162
163
  """카테고리 데이터를 설정한다.
163
164
 
164
165
  Args:
165
166
  data (DataFrame): 데이터프레임 객체
166
167
  *args (str): 컬럼명 목록
168
+ columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
167
169
 
168
170
  Returns:
169
171
  DataFrame: 카테고리 설정된 데이터프레임
170
172
  """
173
+ # columns 인자가 있으면 args보다 우선한다.
174
+ if columns is not None:
175
+ if args:
176
+ raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
177
+ args = columns # type: ignore
178
+
171
179
  df = data.copy()
172
180
 
173
181
  for k in args:
@@ -219,7 +227,7 @@ def unmelt(
219
227
  # ===================================================================
220
228
  # 지정된 변수의 이상치 테이블로 반환한다
221
229
  # ===================================================================
222
- def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
230
+ def outlier_table(data: DataFrame, *fields: str, columns: list | None = None) -> DataFrame:
223
231
  """수치형 컬럼에 대한 사분위수 및 IQR 기반 이상치 경계를 계산한다.
224
232
 
225
233
  전달된 `fields`가 없으면 데이터프레임의 모든 수치형 컬럼을 대상으로 한다.
@@ -228,6 +236,7 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
228
236
  Args:
229
237
  data (DataFrame): 분석할 데이터프레임.
230
238
  *fields (str): 대상 컬럼명(들). 생략 시 모든 수치형 컬럼 대상.
239
+ columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
231
240
 
232
241
  Returns:
233
242
  DataFrame: Q1, Q2(중앙값), Q3, IQR, 하한, 상한을 포함한 통계표.
@@ -236,6 +245,11 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
236
245
  from hossam import *
237
246
  hs_prep.outlier_table(df, "value")
238
247
  """
248
+ # columns 인자가 있으면 args보다 우선한다.
249
+ if columns is not None:
250
+ if args: # type: ignore
251
+ raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
252
+ args = columns
239
253
 
240
254
  target_fields = list(fields) if fields else list(data.select_dtypes(include=[np.number]).columns)
241
255
  result = []
@@ -273,7 +287,7 @@ def outlier_table(data: DataFrame, *fields: str) -> DataFrame:
273
287
  # ===================================================================
274
288
  # 이상치를 대체값(NaN, 0) 또는 중앙값으로 교체한다
275
289
  # ===================================================================
276
- def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> DataFrame:
290
+ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str, columns: list | None = None) -> DataFrame:
277
291
  """이상치 경계값을 넘어가는 데이터를 경계값으로 대체한다.
278
292
 
279
293
  Args:
@@ -285,10 +299,16 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> Data
285
299
  - most: 최빈값 대체
286
300
  - median: 중앙값 대체
287
301
  *fields (str): 컬럼명 목록
302
+ columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
288
303
 
289
304
  Returns:
290
305
  DataFrame: 이상치가 경계값으로 대체된 데이터 프레임
291
306
  """
307
+ # columns 인자가 있으면 args보다 우선한다.
308
+ if columns is not None:
309
+ if args: # type: ignore
310
+ raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
311
+ args = columns
292
312
 
293
313
  # 원본 데이터 프레임 복사
294
314
  df = data.copy()
@@ -335,16 +355,22 @@ def replace_outliner(data: DataFrame, method: str = "nan", *fields: str) -> Data
335
355
  # ===================================================================
336
356
  # 중빈 이상치를 제거한 연처리된 데이터프레임을 반환한다
337
357
  # ===================================================================
338
- def drop_outliner(data: DataFrame, *fields: str) -> DataFrame:
358
+ def drop_outliner(data: DataFrame, *fields: str, columns: list | None = None) -> DataFrame:
339
359
  """이상치를 결측치로 변환한 후 모두 삭제한다.
340
360
 
341
361
  Args:
342
362
  data (DataFrame): 데이터프레임
343
363
  *fields (str): 컬럼명 목록
364
+ columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
344
365
 
345
366
  Returns:
346
367
  DataFrame: 이상치가 삭제된 데이터프레임
347
368
  """
369
+ # columns 인자가 있으면 args보다 우선한다.
370
+ if columns is not None:
371
+ if args: # type: ignore
372
+ raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
373
+ args = columns
348
374
 
349
375
  df = replace_outliner(data, "nan", *fields)
350
376
  return df.dropna()
@@ -353,7 +379,7 @@ def drop_outliner(data: DataFrame, *fields: str) -> DataFrame:
353
379
  # ===================================================================
354
380
  # 범주 변수를 더미 변수(One-Hot 인코딩)로 변환한다
355
381
  # ===================================================================
356
- def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> DataFrame:
382
+ def get_dummies(data: DataFrame, *args: str, columns: list | None = None, drop_first: bool = True, dtype: str = "int") -> DataFrame:
357
383
  """명목형 변수를 더미 변수로 변환한다.
358
384
 
359
385
  컬럼명을 지정하면 그 컬럼들만 더미 변수로 변환하고,
@@ -362,6 +388,7 @@ def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> Da
362
388
  Args:
363
389
  data (DataFrame): 데이터프레임
364
390
  *args (str): 변환할 컬럼명 목록. 지정하지 않으면 숫자형이 아닌 모든 컬럼 자동 선택.
391
+ columns (list, optional): 변환할 컬럼명 목록. args와 중복 사용 불가.
365
392
  drop_first (bool, optional): 첫 번째 더미 변수 제거 여부. 기본값 True.
366
393
  dtype (str, optional): 더미 변수 데이터 타입. 기본값 "int".
367
394
 
@@ -379,19 +406,25 @@ def get_dummies(data: DataFrame, *args: str, drop_first=True, dtype="int") -> Da
379
406
  result = hs_prep.get_dummies(df, 'col1', drop_first=False, dtype='bool')
380
407
  ```
381
408
  """
409
+ # columns 인자가 있으면 args보다 우선한다.
410
+ if columns is not None:
411
+ if args:
412
+ raise ValueError("args와 columns 인자는 중복 사용할 수 없습니다.")
413
+ args = columns # type: ignore
414
+
382
415
  if not args:
383
416
  # args가 없으면 숫자 타입이 아닌 모든 컬럼 자동 선택
384
417
  cols_to_convert = []
385
418
  for f in data.columns:
386
419
  if not pd.api.types.is_numeric_dtype(data[f]):
387
420
  cols_to_convert.append(f)
388
- args = cols_to_convert
421
+ args = cols_to_convert # type: ignore
389
422
  else:
390
423
  # args가 있으면 그 컬럼들만 사용 (존재 여부 확인)
391
- 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
392
425
 
393
426
  # pandas.get_dummies 사용 (재귀 문제 없음)
394
- 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
395
428
 
396
429
 
397
430
  # ===================================================================
@@ -598,7 +631,7 @@ def bin_continuous(
598
631
  if apply_labels:
599
632
  # 숫자 인덱스 사용 (0, 1, 2, ...)
600
633
  numeric_labels = list(range(len(edges) - 1))
601
- 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
602
635
  else:
603
636
  # 문자 레이블 적용
604
637
  if labels is None:
@@ -613,9 +646,9 @@ def bin_continuous(
613
646
  except:
614
647
  pass
615
648
  auto_labels.append(f"{left}~{right}")
616
- 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
617
650
  else:
618
- 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
619
652
 
620
653
  df[new_col] = df[new_col].astype("category")
621
654
  return df
@@ -639,26 +672,24 @@ def bin_continuous(
639
672
  n_bins = len(edges) - 1
640
673
  if apply_labels:
641
674
  numeric_labels = list(range(n_bins))
642
- 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
643
676
  else:
644
677
  if labels is None:
645
678
  position_labels = [f"Q{i+1}" for i in range(n_bins)]
646
- df[new_col] = pd.cut(
647
- series, bins=edges, labels=position_labels, include_lowest=True, ordered=False
648
- )
679
+ df[new_col] = pd.cut(series, bins=edges, labels=position_labels, include_lowest=True, ordered=False) # type: ignore
649
680
  else:
650
- 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
651
682
  df[new_col] = df[new_col].astype("category")
652
683
  return df
653
684
 
654
685
  # 자연 구간화 (Jenks) - 의존성 없으면 분위수로 폴백
655
686
  if method_key in {"natural_breaks", "natural", "jenks"}:
656
687
  k = bins if isinstance(bins, int) and bins > 1 else 5
657
- series_nonnull = series.dropna()
688
+ series_nonnull = series.dropna() # type: ignore
658
689
  k = min(k, max(2, series_nonnull.nunique()))
659
690
  edges = None
660
691
  try:
661
- 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
662
693
  edges[0] = -np.inf
663
694
  edges[-1] = np.inf
664
695
  except Exception:
@@ -698,7 +729,7 @@ def bin_continuous(
698
729
  if apply_labels:
699
730
  # 숫자 인덱스 사용
700
731
  numeric_labels = list(range(len(cut_edges) - 1))
701
- 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
702
733
  else:
703
734
  if labels is None:
704
735
  auto_labels = []
@@ -712,9 +743,9 @@ def bin_continuous(
712
743
  except:
713
744
  pass
714
745
  auto_labels.append(f"{left}~{right}")
715
- 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
716
747
  else:
717
- 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
718
749
  df[new_col] = df[new_col].astype("category")
719
750
  return df
720
751