hossam 0.4.7__tar.gz → 0.4.9__tar.gz

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: hossam
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Hossam Data Helper
5
5
  Author-email: Lee Kwang-Ho <leekh4232@gmail.com>
6
6
  License-Expression: MIT
@@ -73,7 +73,7 @@ title: 🎓 Hossam Data Helper
73
73
  pip install hossam
74
74
  ```
75
75
 
76
- **요구사항**: Python 3.8 이상
76
+ **요구사항**: Python 3.13.9 이상
77
77
 
78
78
  ## 📚 전체 문서
79
79
 
@@ -83,9 +83,9 @@ pip install hossam
83
83
 
84
84
  - **hs_plot**: 25+ 시각화 함수 (선 그래프, 산점도, 히스토그램, 박스플롯, 히트맵 등)
85
85
  - **hs_stats**: 회귀/분류 분석, 교차검증, 정규성 검정, 상관분석 등
86
- - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩
86
+ - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩 등의 데이터 전처리 기능
87
+ - **hs_timeserise**: 시계열 분석 기능 지원
87
88
  - **hs_gis**: GIS 데이터 로드 및 시각화 (대한민국 지도 지원)
88
- - **hs_classroom**: 학습용 이진분류, 다중분류, 회귀 데이터 생성
89
89
  - **hs_util**: 예쁜 테이블 출력, 그리드 서치 등
90
90
 
91
91
  자세한 사용법은 [API 문서](https://py.hossam.kr/api/hossam/)를 참고하세요.
@@ -29,7 +29,7 @@ title: 🎓 Hossam Data Helper
29
29
  pip install hossam
30
30
  ```
31
31
 
32
- **요구사항**: Python 3.8 이상
32
+ **요구사항**: Python 3.13.9 이상
33
33
 
34
34
  ## 📚 전체 문서
35
35
 
@@ -39,9 +39,9 @@ pip install hossam
39
39
 
40
40
  - **hs_plot**: 25+ 시각화 함수 (선 그래프, 산점도, 히스토그램, 박스플롯, 히트맵 등)
41
41
  - **hs_stats**: 회귀/분류 분석, 교차검증, 정규성 검정, 상관분석 등
42
- - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩
42
+ - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩 등의 데이터 전처리 기능
43
+ - **hs_timeserise**: 시계열 분석 기능 지원
43
44
  - **hs_gis**: GIS 데이터 로드 및 시각화 (대한민국 지도 지원)
44
- - **hs_classroom**: 학습용 이진분류, 다중분류, 회귀 데이터 생성
45
45
  - **hs_util**: 예쁜 테이블 출력, 그리드 서치 등
46
46
 
47
47
  자세한 사용법은 [API 문서](https://py.hossam.kr/api/hossam/)를 참고하세요.
@@ -8,6 +8,7 @@ from . import hs_timeserise
8
8
  from . import hs_util
9
9
  from .hs_util import load_info
10
10
  from .hs_util import _load_data_remote as load_data
11
+ from .hs_plot import visualize_silhouette
11
12
 
12
13
  # py-modules
13
14
  import sys
@@ -24,7 +25,7 @@ except Exception:
24
25
 
25
26
  my_dpi = hs_plot.config.dpi
26
27
 
27
- __all__ = ["my_dpi", "load_data", "load_info", "hs_classroom", "hs_gis", "hs_plot", "hs_prep", "hs_stats", "hs_timeserise", "hs_util"]
28
+ __all__ = ["my_dpi", "load_data", "load_info", "hs_classroom", "hs_gis", "hs_plot", "hs_prep", "hs_stats", "hs_timeserise", "hs_util", "visualize_silhouette"]
28
29
 
29
30
  # 내부 모듈에서 hs_fig를 사용할 때는 아래와 같이 import 하세요.
30
31
  # from hossam import hs_fig
@@ -22,12 +22,16 @@ from statsmodels.nonparametric.smoothers_lowess import lowess as sm_lowess
22
22
  from statannotations.Annotator import Annotator
23
23
 
24
24
  # ===================================================================
25
+ from sklearn.cluster._kmeans import KMeans
26
+
25
27
  from sklearn.metrics import (
26
28
  mean_squared_error,
27
29
  ConfusionMatrixDisplay,
28
30
  roc_curve,
29
31
  auc,
30
- confusion_matrix
32
+ confusion_matrix,
33
+ silhouette_score,
34
+ silhouette_samples
31
35
  )
32
36
 
33
37
  # ===================================================================
@@ -708,6 +712,8 @@ def scatterplot(
708
712
  xname: str,
709
713
  yname: str,
710
714
  hue=None,
715
+ vector: str | None = None,
716
+ outline: bool = False,
711
717
  title: str | None = None,
712
718
  palette: str | None = None,
713
719
  width: int = config.width,
@@ -726,6 +732,8 @@ def scatterplot(
726
732
  xname (str): x축 컬럼.
727
733
  yname (str): y축 컬럼.
728
734
  hue (str|None): 범주 컬럼.
735
+ vector (str|None): 벡터 종류 컬럼.
736
+ outline (bool): 점 외곽선 표시 여부.
729
737
  title (str|None): 그래프 제목.
730
738
  palette (str|None): 팔레트 이름.
731
739
  width (int): 캔버스 가로 픽셀.
@@ -745,9 +753,32 @@ def scatterplot(
745
753
  fig, ax = get_default_ax(width, height, 1, 1, dpi) # type: ignore
746
754
  outparams = True
747
755
 
756
+
757
+ if outline and hue is not None:
758
+ # 군집별 값의 종류별로 반복 수행
759
+ for c in df[hue].unique():
760
+ if c == -1:
761
+ continue
762
+
763
+ # 한 종류만 필터링한 결과에서 두 변수만 선택
764
+ df_c = df.loc[df[hue] == c, [xname, yname]]
765
+
766
+ try:
767
+ # 외각선 좌표 계산
768
+ hull = ConvexHull(df_c)
769
+
770
+ # 마지막 좌표 이후에 첫 번째 좌표를 연결
771
+ points = np.append(hull.vertices, hull.vertices[0])
772
+
773
+ ax.plot( # type: ignore
774
+ df_c.iloc[points, 0], df_c.iloc[points, 1], linewidth=linewidth, linestyle=":"
775
+ )
776
+ ax.fill(df_c.iloc[points, 0], df_c.iloc[points, 1], alpha=0.1) # type: ignore
777
+ except:
778
+ pass
779
+
748
780
  # hue가 있을 때만 palette 사용, 없으면 color 사용
749
781
  scatterplot_kwargs = {
750
- "data": df,
751
782
  "x": xname,
752
783
  "y": yname,
753
784
  "hue": hue,
@@ -762,7 +793,30 @@ def scatterplot(
762
793
 
763
794
  scatterplot_kwargs.update(params)
764
795
 
765
- sb.scatterplot(**scatterplot_kwargs)
796
+ # 백터 종류 구분 필드가 전달되지 않은 경우에는 원본 데이터를 그대로 사용
797
+ if vector is None:
798
+ sb.scatterplot(data=df, **scatterplot_kwargs)
799
+ else:
800
+ # 핵심벡터
801
+ scatterplot_kwargs['edgecolor'] = '#ffffff'
802
+ sb.scatterplot(data=df[df[vector] == "core"], **scatterplot_kwargs)
803
+
804
+ # 외곽백터
805
+ scatterplot_kwargs['edgecolor'] = '#000000'
806
+ scatterplot_kwargs['s'] = 25
807
+ scatterplot_kwargs['marker'] = '^'
808
+ scatterplot_kwargs['linewidth'] = 0.8
809
+ sb.scatterplot(data=df[df[vector] == "border"], **scatterplot_kwargs)
810
+
811
+ # 노이즈벡터
812
+ scatterplot_kwargs['edgecolor'] = None
813
+ scatterplot_kwargs['s'] = 25
814
+ scatterplot_kwargs['marker'] = 'x'
815
+ scatterplot_kwargs['linewidth'] = 2
816
+ scatterplot_kwargs['color'] = '#ff0000'
817
+ scatterplot_kwargs['hue'] = None
818
+ sb.scatterplot(data=df[df[vector] == "noise"], **scatterplot_kwargs)
819
+
766
820
 
767
821
  finalize_plot(ax, callback, outparams, save_path, True, title) # type: ignore
768
822
 
@@ -1479,79 +1533,6 @@ def heatmap(
1479
1533
  finalize_plot(ax, callback, outparams, save_path, True, title) # type: ignore
1480
1534
 
1481
1535
 
1482
- # ===================================================================
1483
- # 클러스터별 볼록 경계막(convex hull)을 그린다
1484
- # ===================================================================
1485
- def convex_hull(
1486
- data: DataFrame,
1487
- xname: str,
1488
- yname: str,
1489
- hue: str | None = None,
1490
- title: str | None = None,
1491
- palette: str | None = None,
1492
- width: int = config.width,
1493
- height: int = config.height,
1494
- linewidth: float = config.line_width,
1495
- dpi: int = config.dpi,
1496
- save_path: str | None = None,
1497
- callback: Callable | None = None,
1498
- ax: Axes | None = None,
1499
- **params,
1500
- ):
1501
- """클러스터별 볼록 껍질(convex hull)과 산점도를 그린다.
1502
-
1503
- Args:
1504
- data (DataFrame): 시각화할 데이터.
1505
- xname (str): x축 컬럼.
1506
- yname (str): y축 컬럼.
1507
- hue (str): 클러스터/범주 컬럼.
1508
- title (str|None): 그래프 제목.
1509
- palette (str|None): 팔레트 이름.
1510
- width (int): 캔버스 가로 픽셀.
1511
- height (int): 캔버스 세로 픽셀.
1512
- linewidth (float): 선 굵기.
1513
- dpi (int): 그림 크기 및 해상도.
1514
- callback (Callable|None): Axes 후처리 콜백.
1515
- ax (Axes|None): 외부에서 전달한 Axes.
1516
- **params: seaborn scatterplot 추가 인자.
1517
-
1518
- Returns:
1519
- None
1520
- """
1521
- outparams = False
1522
-
1523
- if ax is None:
1524
- fig, ax = get_default_ax(width, height, 1, 1, dpi) # type: ignore
1525
- outparams = True
1526
-
1527
- # 군집별 값의 종류별로 반복 수행
1528
- for c in data[hue].unique():
1529
- if c == -1:
1530
- continue
1531
-
1532
- # 한 종류만 필터링한 결과에서 두 변수만 선택
1533
- df_c = data.loc[data[hue] == c, [xname, yname]]
1534
-
1535
- try:
1536
- # 외각선 좌표 계산
1537
- hull = ConvexHull(df_c)
1538
-
1539
- # 마지막 좌표 이후에 첫 번째 좌표를 연결
1540
- points = np.append(hull.vertices, hull.vertices[0])
1541
-
1542
- ax.plot( # type: ignore
1543
- df_c.iloc[points, 0], df_c.iloc[points, 1], linewidth=linewidth, linestyle=":"
1544
- )
1545
- ax.fill(df_c.iloc[points, 0], df_c.iloc[points, 1], alpha=0.1) # type: ignore
1546
- except:
1547
- pass
1548
-
1549
- # convex_hull은 hue가 필수이므로 palette를 그대로 사용
1550
- sb.scatterplot(
1551
- data=data, x=xname, y=yname, hue=hue, palette=palette, ax=ax, **params
1552
- )
1553
- finalize_plot(ax, callback, outparams, save_path, True, title) # type: ignore
1554
-
1555
1536
 
1556
1537
  # ===================================================================
1557
1538
  # KDE와 신뢰구간을 나타낸 그래프를 그린다
@@ -2045,16 +2026,8 @@ def scatter_by_class(
2045
2026
  processed.append([item, yname])
2046
2027
  group = processed
2047
2028
 
2048
- if outline:
2049
- for v in group:
2050
- convex_hull(data=data, xname=v[0], yname=v[1], hue=hue, palette=palette,
2051
- width=width, height=height, linewidth=linewidth, dpi=dpi, callback=callback,
2052
- save_path=save_path)
2053
- else:
2054
- for v in group:
2055
- scatterplot(data=data, xname=v[0], yname=v[1], hue=hue, palette=palette,
2056
- width=width, height=height, linewidth=linewidth, dpi=dpi, callback=callback,
2057
- save_path=save_path) # type: ignore
2029
+ for v in group:
2030
+ scatterplot(data=data, xname=v[0], yname=v[1], outline=outline, hue=hue, palette=palette, width=width, height=height, linewidth=linewidth, dpi=dpi, callback=callback, save_path=save_path) # type: ignore
2058
2031
 
2059
2032
 
2060
2033
  # ===================================================================
@@ -2519,3 +2492,218 @@ def distribution_plot(
2519
2492
  plt.close()
2520
2493
  else:
2521
2494
  plt.show()
2495
+
2496
+
2497
+ def silhouette_plot(
2498
+ estimator: KMeans,
2499
+ data: DataFrame,
2500
+ title: str | None = None,
2501
+ width: int = config.width,
2502
+ height: int = config.height,
2503
+ linewidth: float = config.line_width,
2504
+ dpi: int = config.dpi,
2505
+ save_path: str | None = None,
2506
+ callback: Callable | None = None,
2507
+ ax: Axes | None = None,
2508
+ ) -> None:
2509
+ """
2510
+ 군집분석 결과의 실루엣 플롯을 시각화함.
2511
+
2512
+ Args:
2513
+ estimator (KMeans): 학습된 KMeans 군집 모델 객체.
2514
+ data (DataFrame): 군집분석에 사용된 입력 데이터 (n_samples, n_features).
2515
+ title (str, optional): 플롯 제목. None이면 자동 생성.
2516
+ width (int, optional): 플롯 가로 크기 (inch 단위).
2517
+ height (int, optional): 플롯 세로 크기 (inch 단위).
2518
+ linewidth (float, optional): 기준선 등 선 두께.
2519
+ dpi (int, optional): 플롯 해상도(DPI).
2520
+ save_path (str, optional): 저장 경로 지정 시 파일로 저장.
2521
+ callback (Callable, optional): 추가 커스텀 콜백 함수.
2522
+ ax (Axes, optional): 기존 matplotlib Axes 객체. None이면 새로 생성.
2523
+
2524
+ Returns:
2525
+ None
2526
+
2527
+ Note:
2528
+ - 각 군집별 실루엣 계수 분포를 막대그래프로 시각화
2529
+ - 군집 품질(응집도/분리도) 평가에 활용
2530
+ - 붉은색 세로선은 전체 평균 실루엣 스코어를 의미
2531
+ """
2532
+
2533
+ outparams = False
2534
+ if ax is None:
2535
+ fig, ax = get_default_ax(width, height, 1, 1, dpi) # type: ignore
2536
+ outparams = True
2537
+
2538
+ sil_avg = silhouette_score(X=data, labels=estimator.labels_)
2539
+ sil_values = silhouette_samples(X=data, labels=estimator.labels_)
2540
+
2541
+ y_lower = 10
2542
+
2543
+ # 클러스터링 갯수별로 fill_betweenx( )형태의 막대 그래프 표현.
2544
+ for i in range(estimator.n_clusters): # type: ignore
2545
+ ith_cluster_sil_values = sil_values[estimator.labels_ == i] # type: ignore
2546
+ ith_cluster_sil_values.sort() # type: ignore
2547
+
2548
+ size_cluster_i = ith_cluster_sil_values.shape[0] # type: ignore
2549
+ y_upper = y_lower + size_cluster_i
2550
+
2551
+ ax.fill_betweenx( # type: ignore
2552
+ np.arange(y_lower, y_upper),
2553
+ 0,
2554
+ ith_cluster_sil_values,
2555
+ alpha=0.7,
2556
+ )
2557
+ ax.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i)) # type: ignore
2558
+ y_lower = y_upper + 10
2559
+
2560
+ ax.axvline(x=sil_avg, color="red", linestyle="--", linewidth=linewidth) # type: ignore
2561
+
2562
+ ax.set_xlabel("The silhouette coefficient values") # type: ignore
2563
+ ax.set_ylabel("Cluster label") # type: ignore
2564
+ ax.set_xlim([-0.1, 1]) # type: ignore
2565
+ ax.set_ylim([0, len(data) + (estimator.n_clusters + 1) * 10]) # type: ignore
2566
+ ax.set_yticks([]) # type: ignore
2567
+ ax.set_xticks([0, 0.2, 0.4, 0.6, 0.8, 1]) # type: ignore
2568
+
2569
+ if title is None:
2570
+ title = "Number of Cluster : " + str(estimator.n_clusters) + ", Silhouette Score :" + str(round(sil_avg, 3)) # type: ignore
2571
+
2572
+ finalize_plot(ax, callback, outparams, save_path, True, title) # type: ignore
2573
+
2574
+
2575
+ def cluster_plot(
2576
+ estimator: KMeans,
2577
+ data: DataFrame,
2578
+ xname: str | None = None,
2579
+ yname: str | None = None,
2580
+ hue: str | None = None,
2581
+ title: str | None = None,
2582
+ palette: str | None = None,
2583
+ outline: bool = False,
2584
+ width: int = config.width,
2585
+ height: int = config.height,
2586
+ linewidth: float = config.line_width,
2587
+ dpi: int = config.dpi,
2588
+ save_path: str | None = None,
2589
+ ax: Axes | None = None,
2590
+ ) -> None:
2591
+
2592
+ """
2593
+ 2차원 공간에서 군집분석 결과를 산점도로 시각화함.
2594
+
2595
+ Args:
2596
+ estimator (KMeans): 학습된 KMeans 군집 모델 객체.
2597
+ data (DataFrame): 군집분석에 사용된 입력 데이터 (n_samples, n_features).
2598
+ xname (str, optional): x축에 사용할 컬럼명. None이면 첫 번째 컬럼 사용.
2599
+ yname (str, optional): y축에 사용할 컬럼명. None이면 두 번째 컬럼 사용.
2600
+ hue (str, optional): 군집 구분에 사용할 컬럼명. None이면 'cluster' 자동 생성.
2601
+ title (str, optional): 플롯 제목. None이면 기본값 사용.
2602
+ palette (str, optional): 색상 팔레트.
2603
+ outline (bool, optional): 외곽선 표시 여부.
2604
+ width (int, optional): 플롯 가로 크기 (inch 단위).
2605
+ height (int, optional): 플롯 세로 크기 (inch 단위).
2606
+ linewidth (float, optional): 중심점 등 선 두께.
2607
+ dpi (int, optional): 플롯 해상도(DPI).
2608
+ save_path (str, optional): 저장 경로 지정 시 파일로 저장.
2609
+ ax (Axes, optional): 기존 matplotlib Axes 객체. None이면 새로 생성.
2610
+
2611
+ Returns:
2612
+ None
2613
+
2614
+ Example:
2615
+ ```python
2616
+ cluster_plot(estimator, data, xname='Sepal.Length', yname='Sepal.Width')
2617
+ ```
2618
+
2619
+ Note:
2620
+ - 각 군집별 산점도와 중심점(빨간색 원/숫자) 표시
2621
+ - 2차원 특성 공간에서 군집 분포와 분리도 시각화
2622
+ """
2623
+ outparams = False
2624
+ if ax is None:
2625
+ fig, ax = get_default_ax(width, height, 1, 1, dpi) # type: ignore
2626
+ outparams = True
2627
+
2628
+ df = data.copy()
2629
+
2630
+ if not hue:
2631
+ df['cluster'] = estimator.labels_ # type: ignore
2632
+ hue = 'cluster'
2633
+
2634
+ if xname is None:
2635
+ xname = df.columns[0] # type: ignore
2636
+
2637
+ if yname is None:
2638
+ yname = df.columns[1] # type: ignore
2639
+
2640
+ xindex = df.columns.get_loc(xname) # type: ignore
2641
+ yindex = df.columns.get_loc(yname) # type: ignore
2642
+
2643
+ def callback(ax: Axes) -> None:
2644
+ # 클러스터 중심점 표시
2645
+ centers = estimator.cluster_centers_ # type: ignore
2646
+ ax.scatter( # type: ignore
2647
+ centers[:, xindex],
2648
+ centers[:, yindex],
2649
+ marker="o",
2650
+ color="white",
2651
+ alpha=1,
2652
+ s=200,
2653
+ edgecolor="r",
2654
+ linewidth=linewidth
2655
+ )
2656
+
2657
+ for i, c in enumerate(centers):
2658
+ ax.scatter(c[xindex], c[yindex], marker="$%d$" % i, alpha=1, s=50, edgecolor="k")
2659
+
2660
+ ax.set_xlabel("Feature space for the " + xname)
2661
+ ax.set_ylabel("Feature space for the " + yname)
2662
+
2663
+ scatterplot(
2664
+ df=df,
2665
+ xname=xname,
2666
+ yname=yname,
2667
+ hue=hue,
2668
+ title="The visualization of the clustered data." if title is None else title,
2669
+ outline=outline,
2670
+ palette=palette,
2671
+ width=width,
2672
+ height=height,
2673
+ linewidth=linewidth,
2674
+ dpi=dpi,
2675
+ save_path=save_path,
2676
+ callback=callback,
2677
+ ax=ax
2678
+ )
2679
+
2680
+ def visualize_silhouette(estimator: KMeans, data: DataFrame) -> None:
2681
+ """
2682
+ 군집분석 결과의 실루엣 플롯과 군집 산점도를 한 화면에 함께 시각화함.
2683
+
2684
+ Args:
2685
+ estimator (KMeans): 학습된 KMeans 군집 모델 객체.
2686
+ data (DataFrame): 군집분석에 사용된 입력 데이터 (n_samples, n_features).
2687
+
2688
+ Returns:
2689
+ None
2690
+
2691
+ Note:
2692
+ - 실루엣 플롯(왼쪽)과 2차원 군집 산점도(오른쪽)를 동시에 확인 가능
2693
+ - 군집 품질과 분포를 한눈에 비교·분석할 때 유용
2694
+ """
2695
+ fig, ax = get_default_ax(rows=1, cols=2)
2696
+
2697
+ silhouette_plot(
2698
+ estimator=estimator,
2699
+ data=data,
2700
+ ax=ax[0],
2701
+ )
2702
+
2703
+ cluster_plot(
2704
+ estimator=estimator,
2705
+ data=data,
2706
+ ax=ax[1],
2707
+ )
2708
+
2709
+ finalize_plot(ax)
@@ -123,7 +123,7 @@ def diff(
123
123
  ardict["기각값(Critical Values) %s" % key] = value
124
124
 
125
125
  stationarity = ar[1] <= 0.05
126
- ardict["데이터 정상성 여부"] = "정상" if stationarity else "비정상"
126
+ ardict["데이터 정상성 여부"] = "정상" if stationarity else "비정상" # type: ignore
127
127
 
128
128
  ardf = DataFrame(ardict, index=["ADF Test"]).T
129
129
  pretty_table(ardf)
@@ -2,6 +2,10 @@
2
2
  # -------------------------------------------------------------
3
3
  import requests
4
4
  import json
5
+ import tempfile
6
+ import zipfile
7
+ import shutil
8
+ from pathlib import Path
5
9
  from typing import TYPE_CHECKING
6
10
  from importlib.metadata import distributions
7
11
  import pandas as pd
@@ -21,6 +25,42 @@ def __get_df(path: str, index_col=None) -> DataFrame:
21
25
  p = path.rfind(".")
22
26
  exec = path[p+1:].lower()
23
27
 
28
+ # 파일 확장자가 압축파일인 경우 로컬에 파일을 다운로드 후 압축 해제
29
+ if exec == "zip":
30
+ tmp_dir = Path(tempfile.mkdtemp())
31
+ zip_path = tmp_dir / "data.zip"
32
+
33
+ # 원격 URL인 경우 파일 다운로드
34
+ if path.lower().startswith(('http://', 'https://')):
35
+ path = path.replace("\\", "/")
36
+ with requests.Session() as session:
37
+ r = session.get(path)
38
+
39
+ if r.status_code != 200:
40
+ raise Exception(f"HTTP {r.status_code} Error - {r.reason} > {path}")
41
+
42
+ with open(zip_path, "wb") as f:
43
+ f.write(r.content)
44
+ else:
45
+ zip_path = Path(path)
46
+
47
+ # 압축 해제
48
+ with zipfile.ZipFile(zip_path, 'r') as zip_ref:
49
+ zip_ref.extractall(tmp_dir)
50
+
51
+ # 압축 해제된 파일 중 첫 번째 파일을 데이터로 로드
52
+ extracted_files = list(tmp_dir.glob('*'))
53
+ if not extracted_files:
54
+ raise FileNotFoundError("압축 파일 내에 데이터 파일이 없습니다.")
55
+
56
+ path = str(extracted_files[0])
57
+ p = path.rfind(".")
58
+ exec = path[p+1:].lower()
59
+
60
+ # 생성된 임시 디렉토리 삭제
61
+ shutil.rmtree(tmp_dir)
62
+
63
+
24
64
  if exec == 'xlsx':
25
65
  # If path is a remote URL, fetch the file once and reuse the bytes
26
66
  if path.lower().startswith(('http://', 'https://')):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hossam
3
- Version: 0.4.7
3
+ Version: 0.4.9
4
4
  Summary: Hossam Data Helper
5
5
  Author-email: Lee Kwang-Ho <leekh4232@gmail.com>
6
6
  License-Expression: MIT
@@ -73,7 +73,7 @@ title: 🎓 Hossam Data Helper
73
73
  pip install hossam
74
74
  ```
75
75
 
76
- **요구사항**: Python 3.8 이상
76
+ **요구사항**: Python 3.13.9 이상
77
77
 
78
78
  ## 📚 전체 문서
79
79
 
@@ -83,9 +83,9 @@ pip install hossam
83
83
 
84
84
  - **hs_plot**: 25+ 시각화 함수 (선 그래프, 산점도, 히스토그램, 박스플롯, 히트맵 등)
85
85
  - **hs_stats**: 회귀/분류 분석, 교차검증, 정규성 검정, 상관분석 등
86
- - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩
86
+ - **hs_prep**: 결측치 처리, 이상치 탐지, 스케일링, 인코딩 등의 데이터 전처리 기능
87
+ - **hs_timeserise**: 시계열 분석 기능 지원
87
88
  - **hs_gis**: GIS 데이터 로드 및 시각화 (대한민국 지도 지원)
88
- - **hs_classroom**: 학습용 이진분류, 다중분류, 회귀 데이터 생성
89
89
  - **hs_util**: 예쁜 테이블 출력, 그리드 서치 등
90
90
 
91
91
  자세한 사용법은 [API 문서](https://py.hossam.kr/api/hossam/)를 참고하세요.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hossam"
7
- version = "0.4.7"
7
+ version = "0.4.9"
8
8
  description = "Hossam Data Helper"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13.9"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes