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/__init__.py +2 -1
- hossam/hs_classroom.py +30 -30
- hossam/hs_gis.py +17 -18
- hossam/hs_plot.py +334 -347
- hossam/hs_prep.py +36 -31
- hossam/hs_stats.py +1360 -1250
- hossam/hs_timeserise.py +38 -39
- hossam/hs_util.py +202 -7
- {hossam-0.4.4.dist-info → hossam-0.4.6.dist-info}/METADATA +1 -1
- hossam-0.4.6.dist-info/RECORD +15 -0
- hossam/data_loader.py +0 -205
- hossam-0.4.4.dist-info/RECORD +0 -16
- {hossam-0.4.4.dist-info → hossam-0.4.6.dist-info}/WHEEL +0 -0
- {hossam-0.4.4.dist-info → hossam-0.4.6.dist-info}/licenses/LICENSE +0 -0
- {hossam-0.4.4.dist-info → hossam-0.4.6.dist-info}/top_level.txt +0 -0
hossam/data_loader.py
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
# -------------------------------------------------------------
|
|
3
|
-
|
|
4
|
-
import requests
|
|
5
|
-
import json
|
|
6
|
-
from os.path import join, exists
|
|
7
|
-
from io import BytesIO
|
|
8
|
-
from pandas import DataFrame, read_csv, read_excel
|
|
9
|
-
from typing import Optional
|
|
10
|
-
from typing import Optional
|
|
11
|
-
|
|
12
|
-
BASE_URL = "https://data.hossam.kr"
|
|
13
|
-
|
|
14
|
-
# -------------------------------------------------------------
|
|
15
|
-
def __get_df(path: str, index_col=None) -> DataFrame:
|
|
16
|
-
p = path.rfind(".")
|
|
17
|
-
exec = path[p+1:].lower()
|
|
18
|
-
|
|
19
|
-
if exec == 'xlsx':
|
|
20
|
-
# If path is a remote URL, fetch the file once and reuse the bytes
|
|
21
|
-
if path.lower().startswith(('http://', 'https://')):
|
|
22
|
-
path = path.replace("\\", "/")
|
|
23
|
-
with requests.Session() as session:
|
|
24
|
-
r = session.get(path)
|
|
25
|
-
|
|
26
|
-
if r.status_code != 200:
|
|
27
|
-
raise Exception(f"HTTP {r.status_code} Error - {r.reason} > {path}")
|
|
28
|
-
|
|
29
|
-
data_bytes = r.content
|
|
30
|
-
|
|
31
|
-
# Use separate BytesIO objects for each read to avoid pointer/stream issues
|
|
32
|
-
df = read_excel(BytesIO(data_bytes), index_col=index_col)
|
|
33
|
-
|
|
34
|
-
try:
|
|
35
|
-
info = read_excel(BytesIO(data_bytes), sheet_name='metadata', index_col=0)
|
|
36
|
-
#print("\033[94m[metadata]\033[0m")
|
|
37
|
-
print()
|
|
38
|
-
from .util import hs_pretty_table
|
|
39
|
-
hs_pretty_table(info)
|
|
40
|
-
print()
|
|
41
|
-
except Exception:
|
|
42
|
-
#print(f"\033[91m[!] Cannot read metadata\033[0m")
|
|
43
|
-
pass
|
|
44
|
-
else:
|
|
45
|
-
df = read_excel(path, index_col=index_col)
|
|
46
|
-
|
|
47
|
-
try:
|
|
48
|
-
info = read_excel(path, sheet_name='metadata', index_col=0)
|
|
49
|
-
#print("\033[94m[metadata]\033[0m")
|
|
50
|
-
print()
|
|
51
|
-
from .util import hs_pretty_table
|
|
52
|
-
hs_pretty_table(info)
|
|
53
|
-
print()
|
|
54
|
-
except:
|
|
55
|
-
#print(f"\033[91m[!] Cannot read metadata\033[0m")
|
|
56
|
-
pass
|
|
57
|
-
else:
|
|
58
|
-
df = read_csv(path, index_col=index_col)
|
|
59
|
-
|
|
60
|
-
return df
|
|
61
|
-
|
|
62
|
-
# -------------------------------------------------------------
|
|
63
|
-
def __get_data_url(key: str, local: str = None) -> str:
|
|
64
|
-
global BASE_URL
|
|
65
|
-
|
|
66
|
-
path = None
|
|
67
|
-
|
|
68
|
-
if not local:
|
|
69
|
-
data_path = join(BASE_URL, "metadata.json").replace("\\", "/")
|
|
70
|
-
|
|
71
|
-
with requests.Session() as session:
|
|
72
|
-
r = session.get(data_path)
|
|
73
|
-
|
|
74
|
-
if r.status_code != 200:
|
|
75
|
-
raise Exception("[%d Error] %s" % (r.status_code, r.reason))
|
|
76
|
-
|
|
77
|
-
my_dict = r.json()
|
|
78
|
-
info = my_dict.get(key.lower())
|
|
79
|
-
|
|
80
|
-
if not info:
|
|
81
|
-
raise FileNotFoundError("%s는 존재하지 않는 데이터에 대한 요청입니다." % key)
|
|
82
|
-
|
|
83
|
-
path = join(BASE_URL, info['url'])
|
|
84
|
-
else:
|
|
85
|
-
data_path = join(local, "metadata.json")
|
|
86
|
-
|
|
87
|
-
if not exists(data_path):
|
|
88
|
-
raise FileNotFoundError("존재하지 않는 데이터에 대한 요청입니다.")
|
|
89
|
-
|
|
90
|
-
with open(data_path, "r", encoding="utf-8") as f:
|
|
91
|
-
my_dict = json.loads(f.read())
|
|
92
|
-
|
|
93
|
-
info = my_dict.get(key.lower())
|
|
94
|
-
path = join(local, info['url'])
|
|
95
|
-
|
|
96
|
-
return path, info.get('desc'), info.get('index')
|
|
97
|
-
|
|
98
|
-
# -------------------------------------------------------------
|
|
99
|
-
def load_info(search: str = None, local: str = None) -> DataFrame:
|
|
100
|
-
"""메타데이터에서 사용 가능한 데이터셋 정보를 로드한다.
|
|
101
|
-
|
|
102
|
-
Args:
|
|
103
|
-
search (str, optional): 이름 필터 문자열. 포함하는 항목만 반환.
|
|
104
|
-
local (str, optional): 로컬 메타데이터 경로. None이면 원격(BASE_URL) 사용.
|
|
105
|
-
|
|
106
|
-
Returns:
|
|
107
|
-
DataFrame: name, chapter, desc, url 컬럼을 갖는 테이블
|
|
108
|
-
|
|
109
|
-
Examples:
|
|
110
|
-
```python
|
|
111
|
-
from hossam import *
|
|
112
|
-
info = load_info()
|
|
113
|
-
list(info.columns) #['name', 'chapter', 'desc', 'url']
|
|
114
|
-
```
|
|
115
|
-
"""
|
|
116
|
-
global BASE_URL
|
|
117
|
-
|
|
118
|
-
path = None
|
|
119
|
-
|
|
120
|
-
if not local:
|
|
121
|
-
data_path = join(BASE_URL, "metadata.json").replace("\\", "/")
|
|
122
|
-
|
|
123
|
-
with requests.Session() as session:
|
|
124
|
-
r = session.get(data_path)
|
|
125
|
-
|
|
126
|
-
if r.status_code != 200:
|
|
127
|
-
raise Exception("[%d Error] %s ::: %s" % (r.status_code, r.reason, data_path))
|
|
128
|
-
|
|
129
|
-
my_dict = r.json()
|
|
130
|
-
else:
|
|
131
|
-
data_path = join(local, "metadata.json")
|
|
132
|
-
|
|
133
|
-
if not exists(data_path):
|
|
134
|
-
raise FileNotFoundError("존재하지 않는 데이터에 대한 요청입니다.")
|
|
135
|
-
|
|
136
|
-
with open(data_path, "r", encoding="utf-8") as f:
|
|
137
|
-
my_dict = json.loads(f.read())
|
|
138
|
-
|
|
139
|
-
my_data = []
|
|
140
|
-
for key in my_dict:
|
|
141
|
-
if 'index' in my_dict[key]:
|
|
142
|
-
del my_dict[key]['index']
|
|
143
|
-
|
|
144
|
-
my_dict[key]['url'] = "%s/%s" % (BASE_URL, my_dict[key]['url'])
|
|
145
|
-
my_dict[key]['name'] = key
|
|
146
|
-
|
|
147
|
-
if 'chapter' in my_dict[key]:
|
|
148
|
-
my_dict[key]['chapter'] = ", ".join(my_dict[key]['chapter'])
|
|
149
|
-
else:
|
|
150
|
-
my_dict[key]['chapter'] = '공통'
|
|
151
|
-
|
|
152
|
-
my_data.append(my_dict[key])
|
|
153
|
-
|
|
154
|
-
my_df = DataFrame(my_data)
|
|
155
|
-
my_df2 = my_df.reindex(columns=['name', 'chapter', 'desc', 'url'])
|
|
156
|
-
|
|
157
|
-
if search:
|
|
158
|
-
my_df2 = my_df2[my_df2['name'].str.contains(search.lower())]
|
|
159
|
-
|
|
160
|
-
return my_df2
|
|
161
|
-
|
|
162
|
-
# -------------------------------------------------------------
|
|
163
|
-
def load_data(key: str, local: str = None) -> Optional[DataFrame]:
|
|
164
|
-
"""키로 지정된 데이터셋을 로드한다.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
key (str): 메타데이터에 정의된 데이터 식별자(파일명 또는 별칭)
|
|
168
|
-
local (str, optional): 로컬 메타데이터 경로. None이면 원격(BASE_URL) 사용.
|
|
169
|
-
|
|
170
|
-
Returns:
|
|
171
|
-
DataFrame | None: 성공 시 데이터프레임, 실패 시 None
|
|
172
|
-
|
|
173
|
-
Examples:
|
|
174
|
-
```python
|
|
175
|
-
from hossam import *
|
|
176
|
-
df = load_data('AD_SALES') # 메타데이터에 해당 키가 있어야 함
|
|
177
|
-
```
|
|
178
|
-
"""
|
|
179
|
-
index = None
|
|
180
|
-
try:
|
|
181
|
-
url, desc, index = __get_data_url(key, local=local)
|
|
182
|
-
except Exception as e:
|
|
183
|
-
try:
|
|
184
|
-
print(f"\033[91m{str(e)}\033[0m")
|
|
185
|
-
except Exception:
|
|
186
|
-
print(e)
|
|
187
|
-
return
|
|
188
|
-
|
|
189
|
-
#print("\033[94m[data]\033[0m", url.replace("\\", "/"))
|
|
190
|
-
#print("\033[94m[desc]\033[0m", desc)
|
|
191
|
-
print(f"\033[94m{desc}\033[0m")
|
|
192
|
-
|
|
193
|
-
df = None
|
|
194
|
-
|
|
195
|
-
try:
|
|
196
|
-
df = __get_df(url, index_col=index)
|
|
197
|
-
except Exception as e:
|
|
198
|
-
try:
|
|
199
|
-
print(f"\033[91m{str(e)}\033[0m")
|
|
200
|
-
except Exception:
|
|
201
|
-
print(e)
|
|
202
|
-
return
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return df
|
hossam-0.4.4.dist-info/RECORD
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
hossam/NotoSansKR-Regular.ttf,sha256=0SCufUQwcVWrWTu75j4Lt_V2bgBJIBXl1p8iAJJYkVY,6185516
|
|
2
|
-
hossam/__init__.py,sha256=OkMeP15jt6aCy7QNXMtkO0YRVvgOQYumkb7GuVKrbcs,2712
|
|
3
|
-
hossam/data_loader.py,sha256=oUIsqbHQoRiHA_1tdElDaYo1ipmUB5fYSXYMB5gLOl0,6395
|
|
4
|
-
hossam/hs_classroom.py,sha256=rgayol3U5PSo4rLfdbClfiAtG21bFrASaSW56PUsjus,27144
|
|
5
|
-
hossam/hs_gis.py,sha256=DLogaf5nxJBbG-d8QoH2g8UfZ1omMtmEXDYgNg8jtT0,11410
|
|
6
|
-
hossam/hs_plot.py,sha256=tsJMi2q9SzHRSs25dXsHkkImW-Jk7su1M6TbKwX9koU,83887
|
|
7
|
-
hossam/hs_prep.py,sha256=ocZNGzHzqgasVNLcb_LClTZaAeTYiIg4mzrixeEzBQU,37693
|
|
8
|
-
hossam/hs_stats.py,sha256=LpUG8U9ybnh6qSMW2SKCSDJZTeMhLH2xH2Pj4i7U6TU,114889
|
|
9
|
-
hossam/hs_timeserise.py,sha256=gSj3cPgOGLOZEXhfW1anXbwpoJja847ZY9F8l9piJPE,42601
|
|
10
|
-
hossam/hs_util.py,sha256=8byLj_VR93vS__lyf0xgQKArgMy9qFm2VvZVSCxfQX0,8444
|
|
11
|
-
hossam/leekh.png,sha256=1PB5NQ24SDoHA5KMiBBsWpSa3iniFcwFTuGwuOsTHfI,6395
|
|
12
|
-
hossam-0.4.4.dist-info/licenses/LICENSE,sha256=nIqzhlcFY_2D6QtFsYjwU7BWkafo-rUJOQpDZ-DsauI,941
|
|
13
|
-
hossam-0.4.4.dist-info/METADATA,sha256=R6qOrcnZhbTzUrRK2x9vNksDjw8rVK1DVZrbRIPSPQQ,3676
|
|
14
|
-
hossam-0.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
15
|
-
hossam-0.4.4.dist-info/top_level.txt,sha256=_-7bwjhthHplWhywEaHIJX2yL11CQCaLjCNSBlk6wiQ,7
|
|
16
|
-
hossam-0.4.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|