Learn.py 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784
  1. import pandas as pd
  2. import re
  3. import pandas_profiling as pp
  4. from pyecharts import options as opts
  5. from pyecharts.charts import *
  6. from pyecharts.globals import SymbolType
  7. from pyecharts.components import Table
  8. from pyecharts.globals import GeoType #地图推荐使用GeoType而不是str
  9. from random import randint
  10. from sklearn.model_selection import train_test_split
  11. from sklearn.linear_model import *
  12. from sklearn.neighbors import KNeighborsClassifier,KNeighborsRegressor
  13. import sklearn as sk
  14. from sklearn.feature_extraction import DictVectorizer
  15. import numpy as np
  16. class Form:
  17. def __init__(self, *args, **kwargs):
  18. class DEL: pass
  19. self.Sheet_Dic = {}
  20. self.Clean_Func = {}
  21. self.Clean_Func_Exp = {}
  22. self.DEL = DEL()
  23. self.Name = {'pd': pd, 'DEL': self.DEL, 're': re, 'Sheet': self.Sheet_Dic}
  24. self.R_Dic = {} # 存放所有的图
  25. def get_Sheet(self, name, all_Row=None, all_Colunms=None) -> pd.DataFrame:
  26. try:
  27. pd.set_option('display.max_rows', all_Row)
  28. pd.set_option('display.max_columns', all_Colunms)
  29. except:
  30. pass
  31. return self.Sheet_Dic[name]
  32. def Describe(self, name, make_Sheet=False): # 生成描述
  33. get = self.get_Sheet(name)
  34. Des = get.describe()
  35. if make_Sheet: self.Add_Form(Des, f'{name}_describe[{len(self.Sheet_Dic)}]')
  36. shape = get.shape
  37. dtype = get.dtypes
  38. n = get.ndim
  39. head = get.head()
  40. tail = get.tail(3)
  41. return f'1)基本\n{Des}\n\n2)形状:{shape}\n\n3)数据类型\n{dtype}\n\n4)数据维度:{n}\n\n5)头部数据\n{head}\n\n6)尾部数据\n{tail}' \
  42. f'\n\n7)行名\n{get.index}\n\n8)列名\n{get.columns}'
  43. def Add_Form(self, Data, name=''):
  44. if name == '': name = f'Sheet[{len(self.Sheet_Dic)}]'
  45. else:name += f'_[{len(self.Sheet_Dic)}]'
  46. self.Sheet_Dic[name] = Data
  47. return Data
  48. def Del_Form(self,name):
  49. del self.Sheet_Dic[name]
  50. def __Add_Form(self, Dic, Func, name='', Index=True, **kwargs): # 新增表格的核心方式
  51. try:
  52. Data = Func(Dic, **kwargs)
  53. except UnicodeDecodeError: # 找不到编码方式
  54. return False
  55. if not Index:
  56. Data.index = Data.iloc[:, 0].tolist()
  57. Data.drop(Data.columns.values.tolist()[0], inplace=True, axis=1)
  58. return self.Add_Form(Data, name)
  59. def Add_CSV(self, Dic, name='', Sep=',', code='utf-8', str_=True, Index=True):
  60. if str_:
  61. k = {'dtype': 'object'}
  62. else:
  63. k = {}
  64. return self.__Add_Form(Dic, pd.read_csv, name, Index, sep=Sep, encoding=code, **k)
  65. def Add_Python(self, Text, sheet_name='') -> pd.DataFrame:
  66. name = {'Sheet': self.get_Sheet}
  67. name.update(globals().copy())
  68. name.update(locals().copy())
  69. exec(Text, name)
  70. exec('get = Creat()', name)
  71. if isinstance(name['get'], pd.DataFrame): # 已经是DataFram
  72. get = name['get']
  73. elif isinstance(name['get'], np.array):
  74. if bool(name.get('downNdim',False)):#执行降或升维操作
  75. a = name['get']
  76. array = []
  77. for i in a:
  78. try:
  79. c = i.np.ravel(a[i], 'C')
  80. array.append(c)
  81. except:
  82. array.append(i)
  83. get = pd.DataFrame(array)
  84. else:
  85. array = name['get'].tolist()
  86. get = pd.DataFrame(array)
  87. else:
  88. try:
  89. get = pd.DataFrame(name['get'])
  90. except:
  91. get = pd.DataFrame([name['get']])
  92. self.Add_Form(get, sheet_name)
  93. return get
  94. def Add_Html(self, Dic, name='', code='utf-8', str_=True, Index=True):
  95. if str_:
  96. k = {'dtype': 'object'}
  97. else:
  98. k = {}
  99. return self.__Add_Form(Dic, pd.read_html, name, Index, encoding=code, **k)
  100. def get_FormList(self):
  101. return list(self.Sheet_Dic.keys()) # 返回列表
  102. def to_Html_One(self,name,Dic=''):
  103. if Dic == '': Dic = f'{name}.html'
  104. get = self.get_Sheet(name)
  105. headers = [f'{name}'] + self.get_Column(name, True).tolist()
  106. rows = []
  107. table = Table()
  108. for i in get.iterrows(): # 按行迭代
  109. q = i[1].tolist()
  110. rows.append([f'{i[0]}'] + q)
  111. table.add(headers, rows).set_global_opts(
  112. title_opts=opts.ComponentTitleOpts(title=f"表格:{name}", subtitle="CoTan~数据处理:查看表格"))
  113. table.render(Dic)
  114. return Dic
  115. def to_Html(self, name, Dic='', type_=0):
  116. if Dic == '': Dic = f'{name}.html'
  117. # 把要画的sheet放到第一个
  118. Sheet_Dic = self.Sheet_Dic.copy()
  119. del Sheet_Dic[name]
  120. Sheet_list = [name] + list(Sheet_Dic.keys())
  121. class TAB_F:
  122. def __init__(self, q):
  123. self.tab = q # 一个Tab
  124. def render(self, Dic):
  125. return self.tab.render(Dic)
  126. # 生成一个显示页面
  127. if type_ == 0:
  128. class TAB(TAB_F):
  129. def add(self, table, k, *f):
  130. self.tab.add(table, k)
  131. tab = TAB(Tab(page_title='CoTan:查看表格')) # 一个Tab
  132. elif type_ == 1:
  133. class TAB(TAB_F):
  134. def add(self, table, *k):
  135. self.tab.add(table)
  136. tab = TAB(Page(page_title='CoTan:查看表格', layout=Page.DraggablePageLayout))
  137. else:
  138. class TAB(TAB_F):
  139. def add(self, table, *k):
  140. self.tab.add(table)
  141. tab = TAB(Page(page_title='CoTan:查看表格', layout=Page.SimplePageLayout))
  142. # 迭代添加内容
  143. for name in Sheet_list:
  144. get = self.get_Sheet(name)
  145. headers = [f'{name}'] + self.get_Column(name, True).tolist()
  146. rows = []
  147. table = Table()
  148. for i in get.iterrows(): # 按行迭代
  149. q = i[1].tolist()
  150. rows.append([f'{i[0]}'] + q)
  151. table.add(headers, rows).set_global_opts(
  152. title_opts=opts.ComponentTitleOpts(title=f"表格:{name}", subtitle="CoTan~数据处理:查看表格"))
  153. tab.add(table, f'表格:{name}')
  154. tab.render(Dic)
  155. return Dic
  156. def To_Sheet_Des(self, Sheet, Dic):
  157. re = pp.ProfileReport(Sheet)
  158. re.to_file(Dic)
  159. def to_Report(self, name, Dic=''):
  160. if Dic == '': Dic = f'{name}.html'
  161. Sheet = self.get_Sheet(name)
  162. self.To_Sheet_Des(Sheet, Dic)
  163. return Dic
  164. def get_Column(self, name, only=False): # 列名
  165. get = self.get_Sheet(name)
  166. if only:
  167. re = get.columns.values
  168. else:
  169. re = []
  170. loc_list = get.columns.values
  171. a = 0
  172. for i in loc_list:
  173. data = get[i].to_list()
  174. re.append(f'[列号:{a}]{i} -> {data}')
  175. a += 1
  176. return re
  177. def get_Index(self, name, only=False):
  178. get = self.get_Sheet(name)
  179. if only:
  180. re = get.index.values
  181. else:
  182. re = []
  183. loc_list = get.index.values
  184. a = 0
  185. for i in range(len(loc_list)):
  186. l = loc_list[i]
  187. data = get.iloc[i].to_list()
  188. re.append(f'[行号:{a}]{l} -> {data}')
  189. a += 1
  190. return re
  191. def Sorted(self, name, row: bool, new=False, a=True):
  192. get = self.get_Sheet(name)
  193. if row: # row-行名排序
  194. so = get.sort_index(axis=0, ascending=a)
  195. else:
  196. so = get.sort_index(axis=1, ascending=a)
  197. if new:
  198. self.Add_Form(so,f'{name}:排序')
  199. return so
  200. def Stored_Valuse(self, name, F, new=False):
  201. get = self.get_Sheet(name)
  202. row = get.columns.values
  203. a = []
  204. b = []
  205. for i in F:
  206. a.append(row[i[0]])
  207. b.append(i[1])
  208. if len(a) == 1:
  209. a = a[0]
  210. b = b[0]
  211. so = get.sort_values(by=a, ascending=b)
  212. if new:
  213. self.Add_Form(so,f'{name}:排序')
  214. return so
  215. def T(self, name, new=True):
  216. get = self.get_Sheet(name)
  217. re = get.T.copy()#复制一份,防止冲突
  218. if new:
  219. self.Add_Form(re,f'{name}.T')
  220. return re
  221. def get_Clice(self, name, Column, Row, U_iloc=True, new=False): # iloc(Row,Column) or loc
  222. get = self.get_Sheet(name)
  223. if U_iloc:
  224. Cli = get.iloc[Row, Column]
  225. else:
  226. Cli = get.loc[Row, Column]
  227. if new:
  228. self.Add_Form(Cli,f'{name}:切片')
  229. return Cli
  230. def Delete(self, name, Column, Row, new):
  231. get = self.get_Sheet(name)
  232. Column_List = get.columns.values
  233. for i in Column:
  234. try:
  235. get = get.drop(Column_List[int(i)], axis=1)
  236. except:
  237. pass
  238. Row_List = get.index.values
  239. for i in Row:
  240. try:
  241. get = get.drop(Row_List[int(i)])
  242. except:
  243. pass
  244. if new:
  245. self.Add_Form(get,f'{name}:删减')
  246. return get
  247. def Done_Bool(self, name, Exp, new=False):
  248. get = self.get_Sheet(name)
  249. try:
  250. re = eval(Exp, {'S': get, 'Sheet': get.iloc})
  251. if new:
  252. self.Add_Form(re,f'{name}:布尔')
  253. return re
  254. except:
  255. return None
  256. # raise
  257. def is_Na(self, name):
  258. get = self.get_Sheet(name)
  259. Na = pd.isna(get)
  260. return Na
  261. def Dropna(self, name, new):
  262. get = self.get_Sheet(name)
  263. Clean = get.dropna(axis=0)
  264. if new:
  265. self.Add_Form(Clean,f'{name}:清洗')
  266. return Clean
  267. def Add_CleanFunc(self, Exp):
  268. Name = self.Name.copy()
  269. try:
  270. exec(Exp, Name)
  271. except:
  272. return False
  273. Sava = {}
  274. Sava['Done_Row'] = Name.get('Done_Row', [])
  275. Sava['Done_Column'] = Name.get('Done_Column', [])
  276. Sava['axis'] = Name.get('axis', True)
  277. Sava['check'] = Name.get('check', lambda data, x, b, c, d, e: True)
  278. Sava['done'] = Name.get('done', lambda data, x, b, c, d, e: data)
  279. print(f'{len(self.Clean_Func)}')
  280. title = f"[{Name.get('name', f'[{len(self.Clean_Func)}')}] Done_Row={Sava['Done_Row']}_Done_Column={Sava['Done_Column']}_axis={Sava['axis']}"
  281. self.Clean_Func[title] = Sava
  282. self.Clean_Func_Exp[title] = Exp
  283. def Return_CleanFunc(self):
  284. return list(self.Clean_Func.keys())
  285. def Delete_CleanFunc(self, key):
  286. try:
  287. del self.Clean_Func[key]
  288. del self.Clean_Func_Exp[key]
  289. except:
  290. pass
  291. def Tra_Clean(self):
  292. self.Clean_Func = {}
  293. self.Clean_Func_Exp = {}
  294. def Return_CleanExp(self, key):
  295. return self.Clean_Func_Exp[key]
  296. def Done_CleanFunc(self, name):
  297. get = self.get_Sheet(name).copy()
  298. for i in list(self.Clean_Func.values()):
  299. Done_Row = i['Done_Row']
  300. Done_Column = i['Done_Column']
  301. if Done_Row == []:
  302. Done_Row = range(get.shape[0]) # shape=[行,列]#不需要回调
  303. if Done_Column == []:
  304. Done_Column = range(get.shape[1]) # shape=[行,列]#不需要回调
  305. if i['axis']:
  306. axis = 0
  307. else:
  308. axis = 1
  309. check = i['check']
  310. done = i['done']
  311. for r in Done_Row:
  312. for c in Done_Column:
  313. try:
  314. n = eval(f"get.iloc[{r},{c}]") # 第一个是行号,然后是列号
  315. r_h = eval(f"get.iloc[{r}]")
  316. c_h = eval(f"get.iloc[:,{c}]")
  317. if not check(n, r, c, get.copy(), r_h.copy(), c_h.copy()):
  318. d = done(n, r, c, get.copy(), r_h.copy(), c_h.copy())
  319. if d == self.DEL:
  320. if axis == 0: # 常规删除
  321. Row_List = get.index.values
  322. get = get.drop(Row_List[int(r)])
  323. else: # 常规删除
  324. Columns_List = get.columns.values
  325. get = get.drop(Columns_List[int(r)], axis=1)
  326. else:
  327. exec(f"get.iloc[{r},{c}] = {d}") # 第一个是行名,然后是列名
  328. except:
  329. pass
  330. self.Add_Form(get,f'{name}:清洗')
  331. return get
  332. def Import_c(self, text):
  333. Name = {}
  334. Name.update(locals())
  335. Name.update(globals())
  336. exec(text, Name)
  337. exec('c = Page()', Name)
  338. self.R_Dic[f'自定义图[{len(self.R_Dic)}]'] = Name['c']
  339. return Name['c']
  340. def retunr_RDic(self):
  341. return self.R_Dic.copy()
  342. def Delete_RDic(self, key):
  343. del self.R_Dic[key]
  344. def Reasonable_Type(self, name, column, dtype, wrong):
  345. get = self.get_Sheet(name).copy()
  346. for i in range(len(column)):
  347. try:
  348. column[i] = int(column[i])
  349. except:
  350. pass
  351. if dtype != '':
  352. func_Dic = {'Num': pd.to_numeric, 'Date': pd.to_datetime, 'Time': pd.to_timedelta}
  353. if column != []:
  354. get.iloc[:, column] = get.iloc[:, column].apply(func_Dic.get(dtype, pd.to_numeric), errors=wrong)
  355. else:
  356. get = get.apply(func_Dic.get(dtype, pd.to_numeric), errors=wrong)
  357. else:
  358. if column != []:
  359. get.iloc[:, column] = get.iloc[:, column].infer_objects()
  360. print('A')
  361. else:
  362. get = get.infer_objects()
  363. self.Add_Form(get,f'{name}')
  364. return get
  365. def as_Type(self, name, column, dtype, wrong):
  366. get = self.get_Sheet(name).copy()
  367. for i in range(len(column)):
  368. try:
  369. column[i] = int(column[i])
  370. except:
  371. pass
  372. func_Dic = {'Int': int, 'Float': float, 'Str': str, 'Date': pd.Timestamp, 'TimeDelta': pd.Timedelta}
  373. if column != []:
  374. get.iloc[:, column] = get.iloc[:, column].astype(func_Dic.get(dtype, dtype), errors=wrong)
  375. print('A')
  376. else:
  377. get = get.astype(func_Dic.get(dtype, dtype), errors=wrong)
  378. self.Add_Form(get,f'{name}')
  379. return get
  380. def Replace_Index(self, name, is_column, Dic, save):
  381. get = self.get_Sheet(name)
  382. if is_column:
  383. if save: # 保存原数据
  384. get.loc['column'] = self.get_Column(name, True)
  385. new = get.rename(columns=Dic)
  386. else:
  387. if save:
  388. get.loc[:, 'row'] = self.get_Index(name, True)
  389. new = get.rename(index=Dic)
  390. self.Add_Form(new,f'{name}')
  391. return new
  392. def Change_Index(self, name: str, is_column: bool, iloc: int, save: bool = True, drop: bool = False):
  393. get = self.get_Sheet(name).copy()
  394. if is_column: # 列名
  395. Row = self.get_Index(name, True)#行数据
  396. t = Row.tolist()[iloc]
  397. if save: # 保存原数据
  398. get.loc['column'] = self.get_Column(name,True)
  399. # new_colums = get.loc[t].values
  400. get.columns = get.loc[t].values
  401. if drop:
  402. get.drop(t, axis=0, inplace=True) # 删除行
  403. else:
  404. Col = self.get_Column(name, True)
  405. t = Col.tolist()[iloc]
  406. print(t)
  407. if save:
  408. get.loc[:, 'row'] = self.get_Index(name,True)
  409. get.index = get.loc[:, t].values # 调整
  410. if drop:
  411. get.drop(t, axis=1, inplace=True) # 删除行
  412. self.Add_Form(get,f'{name}')
  413. return get
  414. def num_toName(self, name, is_column, save):
  415. get = self.get_Sheet(name).copy()
  416. if is_column: # 处理列名
  417. Col = self.get_Column(name, True)
  418. if save: # 保存原数据
  419. get.loc['column'] = Col
  420. get.columns = [i for i in range(len(Col))]
  421. else:
  422. Row = self.get_Index(name, True)
  423. if save:
  424. get.loc[:, 'row'] = Row
  425. get.index = [i for i in range(len(Row))]
  426. self.Add_Form(get,f'{name}')
  427. return get
  428. def num_withName(self, name, is_column, save):
  429. get = self.get_Sheet(name).copy()
  430. if is_column: # 处理列名
  431. Col = self.get_Column(name, True)
  432. if save: # 保存原数据
  433. get.loc['column'] = Col
  434. get.columns = [f'[{i}]{Col[i]}' for i in range(len(Col))]
  435. else:
  436. Row = self.get_Index(name, True)
  437. if save:
  438. get.loc[:, 'row'] = Row
  439. get.index = [f'[{i}]{Row[i]}' for i in range(len(Row))]
  440. self.Add_Form(get,f'{name}')
  441. return get
  442. def Date_Index(self, name, is_column, save, **Date_Init):
  443. # Date_Init:start,end,freq 任意两样
  444. get = self.get_Sheet(name)
  445. if is_column: # 处理列名
  446. Col = self.get_Column(name, True)
  447. if save: # 保存原数据
  448. get.loc['column'] = Col
  449. Date_Init['periods'] = len(Col)
  450. get.columns = pd.date_range(**Date_Init)
  451. else:
  452. Row = self.get_Index(name, True)
  453. if save:
  454. get.loc[:, 'row'] = Row
  455. Date_Init['periods'] = len(Row)
  456. get.index = pd.date_range(**Date_Init)
  457. self.Add_Form(get,f'{name}')
  458. return get
  459. def Time_Index(self, name, is_column, save, **Time_Init):
  460. # Date_Init:start,end,freq 任意两样
  461. get = self.get_Sheet(name)
  462. if is_column: # 处理列名
  463. Col = self.get_Column(name, True)
  464. if save: # 保存原数据
  465. get.loc['column'] = Col
  466. Time_Init['periods'] = len(Col)
  467. get.columns = pd.timedelta_range(**Time_Init)
  468. else:
  469. Row = self.get_Index(name, True)
  470. if save:
  471. get.loc[:, 'row'] = Row
  472. Time_Init['periods'] = len(Row)
  473. get.index = pd.timedelta_range(**Time_Init)
  474. self.Add_Form(get,f'{name}')
  475. return get
  476. def Sample(self,name,new):
  477. get = self.get_Sheet(name)
  478. sample = get.sample(frac=1)#返回比,默认按行打乱
  479. if new:
  480. self.Add_Form(sample,f'{name}:打乱')
  481. return sample
  482. def to_CSV(self,name,Dic,Sep=','):
  483. if Sep == '':Sep = ','
  484. get = self.get_Sheet(name)
  485. get.to_csv(Dic,sep=Sep,na_rep='')
  486. class Draw(Form):
  487. # 1)图例位置、朝向和是否显示
  488. # 2)视觉映射是否开启、是否有最大值和最小值、两端文本以及颜色、分段和朝向、size或color
  489. # 3)自动设置图标ID,标题
  490. # 4)工具箱显示
  491. # 5)title配置
  492. # 6)是否显示刻度线、数轴类型、分割线
  493. def Parsing_Parameters(self,text):#解析文本参数
  494. args = {}#解析到的参数
  495. exec(text,args)
  496. args_use = {}#真实的参数
  497. #标题设置,global
  498. args_use['title'] = args.get('title',None)
  499. args_use['vice_title'] = args.get('vice_title', 'CoTan~数据处理:')
  500. #图例设置global
  501. args_use['show_Legend'] = bool(args.get('show_Legend', True))#是否显示图例
  502. args_use['ori_Legend'] = args.get('ori_Legend', 'horizontal')#朝向
  503. #视觉映射设置global
  504. args_use['show_Visual_mapping'] = bool(args.get('show_Visual_mapping', True))#是否显示视觉映射
  505. args_use['is_color_Visual_mapping'] = bool(args.get('is_color_Visual_mapping', True))#颜色 or 大小
  506. args_use['min_Visual_mapping'] = args.get('min_Visual_mapping', None)#最小值(None表示现场计算)
  507. args_use['max_Visual_mapping'] = args.get('max_Visual_mapping', None)#最大值(None表示现场计算)
  508. args_use['color_Visual_mapping'] = args.get('color_Visual_mapping', None)#颜色列表
  509. args_use['size_Visual_mapping'] = args.get('size_Visual_mapping', None)#大小列表
  510. args_use['text_Visual_mapping'] = args.get('text_Visual_mapping', None)#文字
  511. args_use['is_Subsection'] = bool(args.get('is_Subsection', False)) # 分段类型
  512. args_use['Subsection_list'] = args.get('Subsection_list', []) # 分段列表
  513. args_use['ori_Visual'] = args.get('ori_Visual', 'vertical') # 朝向
  514. #工具箱设置global
  515. args_use['Tool_BOX'] = bool(args.get('Tool_BOX', True)) # 开启工具箱
  516. #Init设置global
  517. args_use['Theme'] = args.get('Theme', 'white') # 设置style
  518. args_use['BG_Color'] = args.get('BG_Color', None) # 设置背景颜色
  519. args_use['width'] = args.get('width', '900px') # 设置宽度
  520. args_use['heigh'] = args.get('heigh', '500px') if not bool(args.get('Square', False)) else args.get('width', '900px') # 设置高度
  521. args_use['page_Title'] = args.get('page_Title', '') # 设置HTML标题
  522. args_use['show_Animation'] = args.get('show_Animation', True) # 设置HTML标题
  523. #坐标轴设置,2D坐标图和3D坐标图
  524. args_use['show_Axis'] = bool(args.get('show_Axis', True)) # 显示坐标轴
  525. args_use['Axis_Zero'] = bool(args.get('Axis_Zero', False)) # 重叠于原点
  526. args_use['show_Axis_Scale'] = bool(args.get('show_Axis_Scale', True)) # 显示刻度
  527. args_use['x_type'] = args.get('x_type', None) # 坐标轴类型
  528. args_use['y_type'] = args.get('y_type', None)
  529. args_use['z_type'] = args.get('z_type', None)
  530. #Mark设置 坐标图专属
  531. args_use['make_Line'] = args.get('make_Line', []) # 设置直线
  532. #Datazoom设置 坐标图专属
  533. args_use['Datazoom'] = args.get('Datazoom', 'N') # 设置Datazoom
  534. #显示文字设置
  535. args_use['show_Text'] = bool(args.get('show_Text', False)) # 显示文字
  536. #统一化的设置
  537. args_use['Size'] = args.get('Size', 10) # Size
  538. args_use['Symbol'] = args.get('Symbol', 'circle') # 散点样式
  539. #Bar设置
  540. args_use['bar_Stacking'] = bool(args.get('bar_Stacking', False)) # 堆叠(2D和3D)
  541. #散点图设置
  542. args_use['EffectScatter'] = bool(args.get('EffectScatter', False)) # 开启特效(2D和3D)
  543. # 折线图设置
  544. args_use['connect_None'] = bool(args.get('connect_None', False)) # 连接None
  545. args_use['Smooth_Line'] = bool(args.get('Smooth_Line', False)) # 平滑曲线
  546. args_use['Area_chart'] = bool(args.get('Area_chart', False)) # 面积图
  547. args_use['paste_Y'] = bool(args.get('paste_Y', False)) # 紧贴Y轴
  548. args_use['step_Line'] = bool(args.get('step_Line', False)) # 阶梯式图
  549. args_use['size_PictorialBar'] = args.get('size_PictorialBar', None) # 象形柱状图大小
  550. args_use['Polar_units'] = args.get('Polar_units', '100') # 极坐标图单位制
  551. args_use['More'] = bool(args.get('More', False)) # 均绘制水球图、仪表图
  552. args_use['WordCould_Size'] = args.get('WordCould_Size', [20,100]) # 开启特效
  553. args_use['WordCould_Shape'] = args.get('WordCould_Shape', "circle") # 开启特效
  554. args_use['symbol_Graph'] = args.get('symbol_Graph', 'circle') # 关系点样式
  555. args_use['Repulsion'] = float(args.get('Repulsion', 8000)) # 斥力因子
  556. args_use['Area_radar'] = bool(args.get('Area_radar', True)) # 雷达图面积
  557. args_use['HTML_Type'] = args.get('HTML_Type', 2) # 输出Page的类型
  558. args_use['Map'] = args.get('Map', 'china') # 输出Page的面积
  559. args_use['show_Map_Symbol'] = bool(args.get('show_Map_Symbol', False)) # 输出Page的面积
  560. args_use['Geo_Type'] = {'heatmap':GeoType.HEATMAP,'scatter':'scatter','EFFECT':GeoType.EFFECT_SCATTER
  561. }.get(args.get('Geo_Type', 'heatmap'),GeoType.HEATMAP) # 输出Page的面积
  562. args_use['map_Type'] = args.get('map_Type', '2D') # 输出Page的面积
  563. args_use['is_Dark'] = bool(args.get('is_Dark', False)) # 输出Page的面积
  564. return args_use
  565. #全局设定,返回一个全局设定的字典,解包即可使用
  566. def global_set(self,args_use,title,Min,Max,DataZoom=False,Visual_mapping=True,axis=()):
  567. k = {}
  568. #标题设置
  569. if args_use['title'] == None:args_use['title'] = title
  570. k['title_opts']=opts.TitleOpts(title=args_use['title'], subtitle=args_use['vice_title'])
  571. #图例设置
  572. if not args_use['show_Legend']:k['legend_opts']=opts.LegendOpts(is_show=False)
  573. else:
  574. k['legend_opts'] = opts.LegendOpts(type_='scroll',orient=args_use['ori_Legend'],pos_bottom='2%')#移动到底部,避免和标题冲突
  575. #视觉映射
  576. if not args_use['show_Visual_mapping']:
  577. pass
  578. elif not Visual_mapping:
  579. pass
  580. else:
  581. if args_use['min_Visual_mapping'] != None:Min = args_use['min_Visual_mapping']
  582. if args_use['max_Visual_mapping'] != None:Max = args_use['max_Visual_mapping']
  583. k['visualmap_opts'] = opts.VisualMapOpts(type_= 'color'if args_use['is_color_Visual_mapping'] else 'size',
  584. max_=Max,min_=Min,range_color=args_use['color_Visual_mapping'],
  585. range_size=args_use['size_Visual_mapping'],range_text=args_use['text_Visual_mapping'],
  586. is_piecewise=args_use['is_Subsection'],pieces=args_use['Subsection_list'],
  587. orient=args_use['ori_Visual'])
  588. k['toolbox_opts']=opts.ToolboxOpts(is_show=args_use['Tool_BOX'])
  589. if DataZoom:
  590. if args_use['Datazoom'] == 'all':
  591. k['datazoom_opts'] = [opts.DataZoomOpts(), opts.DataZoomOpts(orient = "horizontal")]
  592. elif args_use['Datazoom'] == 'horizontal':
  593. k['datazoom_opts'] = opts.DataZoomOpts(type_="inside")
  594. elif args_use['Datazoom'] == 'vertical':
  595. opts.DataZoomOpts(orient="vertical")
  596. elif args_use['Datazoom'] == 'inside_vertical':
  597. opts.DataZoomOpts(type_="inside", orient="vertical")
  598. elif args_use['Datazoom'] == 'inside_vertical':
  599. opts.DataZoomOpts(type_="inside", orient="horizontal")
  600. # 坐标轴设定,输入设定的坐标轴即可
  601. def axis_Seeting(args_use, axis='x'):
  602. axis_k = {}
  603. if args_use[f'{axis[0]}_type'] == 'Display' or not args_use['show_Axis']:
  604. axis_k[f'{axis[0]}axis_opts'] = opts.AxisOpts(is_show=False)
  605. else:
  606. axis_k[f'{axis[0]}axis_opts'] = opts.AxisOpts(type_=args_use[f'{axis[0]}_type'],
  607. axisline_opts=opts.AxisLineOpts(
  608. is_on_zero=args_use['Axis_Zero']),
  609. axistick_opts=opts.AxisTickOpts(
  610. is_show=args_use['show_Axis_Scale']))
  611. return axis_k
  612. for i in axis:
  613. k.update(axis_Seeting(args_use, i))
  614. return k
  615. #初始化设定
  616. def initSetting(self,args_use):
  617. k = {}
  618. #设置标题
  619. if args_use['page_Title'] == '':title = 'CoTan_数据处理'
  620. else:title = f"CoTan_数据处理:{args_use['page_Title']}"
  621. k['init_opts'] = opts.InitOpts(theme=args_use['Theme'],bg_color=args_use['BG_Color'],width=args_use['width'],
  622. height=args_use['heigh'],page_title=title,
  623. animation_opts=opts.AnimationOpts(animation=args_use['show_Animation']))
  624. return k
  625. #获取title专用
  626. def get_name(self,args_use):
  627. return f":{args_use['title']}"
  628. #标记符,包含线标记、点
  629. def Mark(self,args_use):
  630. k = {}
  631. line = []
  632. for i in args_use['make_Line']:
  633. try:
  634. if i[2] == 'c' or i[0] in ('min', 'max', 'average'):
  635. line.append(opts.MarkLineItem(type_=i[0], name=i[1]))
  636. elif i[2] == 'x':
  637. line.append(opts.MarkLineItem(x=i[0], name=i[1]))
  638. else:
  639. raise Exception
  640. except:
  641. line.append(opts.MarkLineItem(y=i[0], name=i[1]))
  642. if line == []:return k
  643. k['markline_opts'] = opts.MarkLineOpts(data=line)
  644. return k
  645. #标签设定,可以放在系列设置中或者坐标轴y轴设置中
  646. def y_Label(self,args_use,position="inside"):
  647. return {'label_opts':opts.LabelOpts(is_show=args_use['show_Text'],position=position)}
  648. #放在不同的图~.add中的设定
  649. def Per_Seeting(self,args_use,type_):#私人设定
  650. k = {}
  651. if type_ == 'Bar':#设置y的重叠
  652. if args_use['bar_Stacking']:
  653. k = {"stack":"stack1"}
  654. elif type_ == 'Scatter':
  655. k['Beautiful'] = args_use['EffectScatter']
  656. k['symbol'] = args_use['Symbol']
  657. k['symbol_size'] = args_use['Size']
  658. elif type_ == 'Line':
  659. k['is_connect_nones'] = args_use['connect_None']
  660. k['is_smooth'] = True if args_use['Smooth_Line'] or args_use['paste_Y'] else False#平滑曲线或连接y轴
  661. k['areastyle_opts']=opts.AreaStyleOpts(opacity=0.5 if args_use['Area_chart'] else 0)
  662. if args_use['step_Line']:
  663. del k['is_smooth']
  664. k['is_step'] = True
  665. elif type_ == 'PictorialBar':
  666. k['symbol_size'] = args_use['Size']
  667. elif type_ == 'Polar':
  668. return args_use['Polar_units']#回复的是单位制而不是设定
  669. elif type_ == 'WordCloud':
  670. k['word_size_range'] = args_use['WordCould_Size']#放到x轴
  671. k['shape'] = args_use['Symbol'] # 放到x轴
  672. elif type_ == 'Graph':
  673. k['symbol_Graph'] = args_use['Symbol']#放到x轴
  674. elif type_ == 'Radar':#雷达图
  675. k['areastyle_opts']=opts.AreaStyleOpts(opacity=0.1 if args_use['Area_chart'] else 0)
  676. k['symbol'] = args_use['Symbol']#雷达图symbol
  677. return k
  678. #坐标系图像:水平和垂直的数据轴:DataZoom+inside
  679. def to_Bar(self,name,text) -> Bar:#Bar:数据堆叠
  680. get = self.get_Sheet(name)
  681. x = self.get_Index(name,True).tolist()
  682. args = self.Parsing_Parameters(text)
  683. c = (
  684. Bar(**self.initSetting(args))
  685. .add_xaxis(list(map(str, list(set(x)))))#转变为str类型
  686. )
  687. y = []
  688. for i in get.iteritems():#按列迭代
  689. q = i[1].tolist()#转换为列表
  690. try:
  691. c.add_yaxis(f'{name}_{i[0]}', q,**self.Per_Seeting(args,'Bar'),**self.y_Label(args),color=self.get_Color())#i[0]是名字,i是tuple,其中i[1]是data
  692. y += list(map(int, q)) # q不需要float,因为应多不同的type他会自动变更,但是y是用来比较大小
  693. except:
  694. pass
  695. if y == []:
  696. args['show_Visual_mapping'] = False # 关闭视觉映射
  697. y = [0,100]
  698. c.set_global_opts(**self.global_set(args,f"{name}柱状图",min(y),max(y),True,axis=['x','y']))
  699. c.set_series_opts(**self.Mark(args))
  700. self.R_Dic[f'{name}柱状图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  701. return c
  702. # 坐标系图像:水平和垂直的数据轴:DataZoom+inside
  703. def to_Line(self,name,text) -> Line:#折线图:连接空数据、显示数值、平滑曲线、面积图以及紧贴Y轴
  704. get = self.get_Sheet(name)
  705. x = self.get_Index(name,True).tolist()
  706. args = self.Parsing_Parameters(text)
  707. c = (
  708. Line(**self.initSetting(args))
  709. .add_xaxis(list(map(str, list(set(x)))))#转变为str类型
  710. )
  711. y = []
  712. for i in get.iteritems():#按列迭代
  713. q = i[1].tolist()#转换为列表
  714. try:
  715. c.add_yaxis(f'{name}_{i[0]}', q,**self.Per_Seeting(args,'Line'),**self.y_Label(args),color=self.get_Color())#i[0]是名字,i是tuple,其中i[1]是data
  716. y += list(map(int, q)) # q不需要float,因为应多不同的type他会自动变更,但是y是用来比较大小
  717. except:
  718. pass
  719. if y == []:
  720. args['show_Visual_mapping'] = False # 关闭视觉映射
  721. y = [0, 100]
  722. c.set_global_opts(**self.global_set(args, f"{name}折线图", min(y), max(y), True,axis=['x','y']))
  723. c.set_series_opts(**self.Mark(args))
  724. self.R_Dic[f'{name}折线图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  725. return c
  726. # 坐标系图像:水平和垂直的数据轴:DataZoom+inside
  727. def to_Scatter(self,name,text) -> Scatter:#散点图标记形状和大小、特效、标记线
  728. get = self.get_Sheet(name)
  729. args = self.Parsing_Parameters(text)
  730. x = self.get_Index(name,True).tolist()
  731. type_ = self.Per_Seeting(args, 'Scatter')
  732. if type_['Beautiful']:Func = EffectScatter
  733. else:Func = Scatter
  734. del type_['Beautiful']
  735. c = (
  736. Func(**self.initSetting(args))
  737. .add_xaxis(list(map(str, list(set(x)))))#转变为str类型
  738. )
  739. y = []
  740. for i in get.iteritems():#按列迭代
  741. q = i[1].tolist()#转换为列表
  742. try:
  743. c.add_yaxis(f'{name}_{i[0]}', q,**type_,**self.y_Label(args),color=self.get_Color())#i[0]是名字,i是tuple,其中i[1]是data
  744. y += list(map(int, q)) # q不需要float,因为应多不同的type他会自动变更,但是y是用来比较大小
  745. except:
  746. pass
  747. if y == []:
  748. args['show_Visual_mapping'] = False # 关闭视觉映射
  749. y = [0, 100]
  750. c.set_global_opts(**self.global_set(args, f"{name}散点图", min(y), max(y), True,axis=['x','y']))
  751. c.set_series_opts(**self.Mark(args))
  752. self.R_Dic[f'{name}散点图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  753. return c
  754. # 坐标系图像:水平和垂直的数据轴:DataZoom+inside
  755. def to_Pictorialbar(self,name,text) -> PictorialBar:#象形柱状图:图形、剪裁图像、元素重复和间隔
  756. get = self.get_Sheet(name)
  757. x = self.get_Index(name, True).tolist()
  758. args = self.Parsing_Parameters(text)
  759. c = (
  760. PictorialBar(**self.initSetting(args))
  761. .add_xaxis(list(map(str, list(set(x)))))#转变为str类型
  762. .reversal_axis()
  763. )
  764. y = []
  765. k = self.Per_Seeting(args, 'PictorialBar')
  766. for i in get.iteritems():#按列迭代
  767. q = i[1].tolist()#转换为列表
  768. try:
  769. c.add_yaxis(
  770. f'{name}_{i[0]}',q,
  771. label_opts=opts.LabelOpts(is_show=False),
  772. symbol_repeat=True,
  773. is_symbol_clip=True,
  774. symbol=SymbolType.ROUND_RECT,
  775. **k,color=self.get_Color())
  776. y += list(map(int, q)) # q不需要float,因为应多不同的type他会自动变更,但是y是用来比较大小
  777. except:
  778. pass
  779. if y == []:
  780. args['show_Visual_mapping'] = False # 关闭视觉映射
  781. y = [0, 100]
  782. c.set_global_opts(**self.global_set(args, f"{name}象形柱状图", min(y), max(y), True,axis=['x','y']))
  783. c.set_series_opts(**self.Mark(args))
  784. self.R_Dic[f'{name}[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  785. return c
  786. # 坐标系图像:水平和垂直的数据轴:DataZoom+inside
  787. def to_Boxpolt(self,name,text) -> Boxplot:
  788. get = self.get_Sheet(name)
  789. args = self.Parsing_Parameters(text)
  790. c = (
  791. Boxplot(**self.initSetting(args))
  792. .add_xaxis([f'{name}'])
  793. )
  794. y = []
  795. for i in get.iteritems():#按列迭代
  796. q = i[1].tolist()#转换为列表
  797. try:
  798. c.add_yaxis(f'{name}_{i[0]}',[q],**self.y_Label(args))
  799. y += list(map(float, q)) # q不需要float,因为应多不同的type他会自动变更,但是y是用来比较大小
  800. except:
  801. pass
  802. if y == []:
  803. args['show_Visual_mapping'] = False # 关闭视觉映射
  804. y = [0, 100]
  805. c.set_global_opts(**self.global_set(args, f"{name}箱形图", min(y), max(y), True,axis=['x','y']))
  806. c.set_series_opts(**self.Mark(args))
  807. self.R_Dic[f'{name}箱形图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  808. return c
  809. # 坐标系图像:水平和垂直的数据轴:DataZoom+inside
  810. def to_HeatMap(self,name,text) -> HeatMap:#显示数据
  811. get = self.get_Sheet(name)
  812. x = self.get_Column(name, True).tolist() # 图的x轴,下侧,列名
  813. y = self.get_Index(name, True).tolist() # 图的y轴,左侧,行名
  814. value_list = []
  815. q = []
  816. for c in range(len(x)): # c-列,r-行
  817. for r in range(len(y)):
  818. try:
  819. v = float(eval(f'get.iloc[{r},{c}]')) # 先行后列
  820. except:continue
  821. q.append(v)
  822. value_list.append([c, r, v])
  823. args = self.Parsing_Parameters(text)
  824. try:
  825. MAX,MIN = max(q),min(q)
  826. except:
  827. args['show_Visual_mapping'] = False # 关闭视觉映射
  828. MAX, MIN = 0,100
  829. c = (
  830. HeatMap(**self.initSetting(args))
  831. .add_xaxis(list(map(str, list(set(x)))))#转变为str类型
  832. .add_yaxis(f'{name}', list(map(str, y)), value_list,**self.y_Label(args))
  833. .set_global_opts(**self.global_set(args, f"{name}热力图", MIN, MAX, True,axis=['x','y']))
  834. .set_series_opts(**self.Mark(args))
  835. )
  836. self.R_Dic[f'{name}热力图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  837. return c
  838. #数据哪部全,要设置More
  839. def to_Funnel(self,name,text) -> Funnel:
  840. get = self.get_Sheet(name)
  841. y_name = self.get_Index(name,True).tolist()#拿行名
  842. x = self.get_Column(name,True).tolist()[0]
  843. value = []
  844. y = []
  845. for r in range(len(y_name)):
  846. try:
  847. v = float(eval(f'get.iloc[{r},0]'))
  848. except:continue
  849. value.append([f'{y_name[r]}',v])
  850. y.append(v)
  851. args = self.Parsing_Parameters(text)
  852. c = (
  853. Funnel(**self.initSetting(args))
  854. .add(f'{name}', value,**self.y_Label(args,'top'))
  855. .set_global_opts(**self.global_set(args, f"{name}漏斗图", min(y), max(y), True, False))
  856. )
  857. self.R_Dic[f'{name}漏斗图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  858. return c
  859. def to_Graph(self,name,text) -> Graph:
  860. get = self.get_Sheet(name)
  861. y_name = self.get_Index(name,True).tolist()#拿行名
  862. nodes = []
  863. link = []
  864. for i in get.iterrows():#按行迭代
  865. q = i[1].tolist()#转换为列表
  866. try:
  867. nodes.append({"name": f"{i[0]}", "symbolSize": float(q[0]),"value": float(q[0])})
  868. for a in q[1:]:
  869. n = str(a).split(':')
  870. try:
  871. link.append({"source": f"{i[0]}", "target": n[0], "value":float(n[1])})
  872. except:pass
  873. except:
  874. pass
  875. if link == []:
  876. for i in nodes:
  877. for j in nodes:
  878. link.append({"source": i.get("name"), "target": j.get("name"),"value":abs(i.get("value")-j.get("value"))})
  879. args = self.Parsing_Parameters(text)
  880. c = (
  881. Graph(**self.initSetting(args))
  882. .add(f"{y_name[0]}", nodes, link, repulsion=args['Repulsion'],**self.y_Label(args))
  883. .set_global_opts(**self.global_set(args, f"{name}关系图", 0, 100, False,False))
  884. )
  885. self.R_Dic[f'{name}关系图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  886. return c
  887. def to_XY_Graph(self,name,text) -> Graph:#XY关系图,新的书写方式
  888. get = self.get_Sheet(name)
  889. args = self.Parsing_Parameters(text)
  890. size = args['Size']*3
  891. #生成节点信息
  892. y_name = self.get_Index(name,True).tolist()#拿行名
  893. x_name = self.get_Column(name,True).tolist()#拿列名
  894. nodes_list = list(set(y_name + x_name))#处理重复,作为nodes列表
  895. nodes = []
  896. for i in nodes_list:
  897. nodes.append({"name": f"{i}", "symbolSize": size})
  898. #生成link信息
  899. link = [] # 记录连接的信息
  900. have = []
  901. for y in range(len(y_name)):#按行迭代
  902. for x in range(len(x_name)):
  903. y_n = y_name[y]#节点1
  904. x_n = x_name[x]#节点2
  905. if y_n == x_n:continue
  906. if (y_n,x_n) in have or (x_n,y_n) in have :continue
  907. else:
  908. have.append((y_n,x_n))
  909. try:
  910. v = float(eval(f'get.iloc[{y},{x}]'))#取得value
  911. link.append({"source": y_n, "target": x_n, "value": v})
  912. except:
  913. pass
  914. c = (
  915. Graph(**self.initSetting(args))
  916. .add(f"{y_name[0]}", nodes, link, repulsion=args['Repulsion'],**self.y_Label(args))
  917. .set_global_opts(**self.global_set(args, f"{name}关系图", 0, 100, False,False))
  918. )
  919. self.R_Dic[f'{name}关系图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  920. return c
  921. def to_Sankey(self,name,text):
  922. get = self.get_Sheet(name)
  923. args = self.Parsing_Parameters(text)
  924. size = args['Size']*3
  925. #生成节点信息
  926. y_name = self.get_Index(name,True).tolist()#拿行名
  927. x_name = self.get_Column(name,True).tolist()#拿列名
  928. nodes_list = list(set(y_name + x_name))#处理重复,作为nodes列表
  929. nodes = []
  930. source = {}
  931. target = {}
  932. for i in nodes_list:
  933. nodes.append({"name": f"{i}"})
  934. source[i] = set()#记录该元素source边连接的节点
  935. target[i] = set()#记录改元素target边连接的节点
  936. #生成link信息
  937. link = [] # 记录连接的信息
  938. have = []
  939. for y in range(len(y_name)):#按行迭代
  940. for x in range(len(x_name)):
  941. y_n = y_name[y]#节点1
  942. x_n = x_name[x]#节点2
  943. if y_n == x_n:continue#是否相同
  944. if (y_n,x_n) in have or (x_n,y_n) in have :continue#是否重复
  945. else:have.append((y_n,x_n))
  946. #固定的,y在s而x在t,桑基图不可以绕环形,所以要做检查
  947. if source[y_n] & target[x_n] != set():continue
  948. try:
  949. v = float(eval(f'get.iloc[{y},{x}]'))#取得value
  950. link.append({"source": y_n, "target": x_n, "value": v})
  951. target[y_n].add(x_n)
  952. source[x_n].add(y_n)
  953. except:
  954. pass
  955. c = (
  956. Sankey()
  957. .add(
  958. f"{name}",
  959. nodes,
  960. link,
  961. linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color="source"),
  962. label_opts=opts.LabelOpts(position="right"),
  963. )
  964. .set_global_opts(**self.global_set(args, f"{name}桑基图", 0, 100, False, False))
  965. )
  966. self.R_Dic[f'{name}桑基图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  967. return c
  968. def to_Parallel(self,name,text) -> Parallel:
  969. get = self.get_Sheet(name)
  970. dim = []
  971. dim_list = self.get_Index(name,True).tolist()
  972. for i in range(len(dim_list)):
  973. dim.append({"dim": i, "name": f"{dim_list[i]}"})
  974. args = self.Parsing_Parameters(text)
  975. c = (
  976. Parallel(**self.initSetting(args))
  977. .add_schema(dim)
  978. .set_global_opts(**self.global_set(args, f"{name}多轴图", 0, 100, False, False))
  979. )
  980. for i in get.iteritems(): # 按列迭代
  981. q = i[1].tolist() # 转换为列表
  982. c.add(f"{i[0]}",[q],**self.y_Label(args))
  983. self.R_Dic[f'{name}多轴图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  984. return c
  985. def to_Pie(self,name,text) -> Pie:
  986. get = self.get_Sheet(name)
  987. data = []
  988. for i in get.iterrows():#按行迭代
  989. try:
  990. data.append([f'{i[0]}',float(i[1].tolist()[0])])
  991. except:pass
  992. args = self.Parsing_Parameters(text)
  993. c = (
  994. Pie(**self.initSetting(args))
  995. .add(f"{name}", data,**self.y_Label(args,'top'))
  996. .set_global_opts(**self.global_set(args, f"{name}饼图", 0, 100, False, False))
  997. .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
  998. )
  999. self.R_Dic[f'{name}饼图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1000. return c
  1001. def to_Polar(self,name,text) -> Polar:
  1002. get = self.get_Sheet(name)
  1003. data = []
  1004. args = self.Parsing_Parameters(text)
  1005. setting = self.Per_Seeting(args, 'Polar')
  1006. if setting == 'rad':#弧度制
  1007. D = 0.0628
  1008. elif setting == '360':#角度制
  1009. D = 0.36
  1010. else:
  1011. D = 1
  1012. for i in get.iterrows():#按行迭代
  1013. try:
  1014. q = i[1].tolist()
  1015. data.append((float(q[0]),float(q[1])/D))
  1016. except:pass
  1017. c = (
  1018. Polar(**self.initSetting(args))
  1019. .add(f"{name}", data, type_="scatter",**self.y_Label(args))
  1020. .set_global_opts(**self.global_set(args, f"{name}极坐标图", 0, 100, False, False))
  1021. )
  1022. self.R_Dic[f'{name}极坐标图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1023. return c
  1024. def to_Radar(self,name,text) -> Radar:
  1025. get = self.get_Sheet(name)
  1026. x = self.get_Index(name,True).tolist()
  1027. Max_list = [[] for i in range(len(x))]#保存每个x栏目的最大值
  1028. data = []#y的组成数据,包括name和list
  1029. x_list = []#保存x的数据
  1030. for i in get.iteritems(): # 按列迭代计算每一项的abcd
  1031. q = i[1].tolist()
  1032. add = []
  1033. for a in range(len(q)):
  1034. try:
  1035. f = float(q[a])
  1036. Max_list[a].append(f)
  1037. add.append(f)
  1038. except:pass
  1039. data.append([f'{i[0]}',[add]])#add是包含在一个list中的
  1040. for i in range(len(Max_list)):#计算x_list
  1041. x_list.append(opts.RadarIndicatorItem(name=x[i], max_=max(Max_list[i])))
  1042. args = self.Parsing_Parameters(text)
  1043. c = (
  1044. Radar(**self.initSetting(args))
  1045. .add_schema(
  1046. schema=x_list
  1047. )
  1048. .set_global_opts(**self.global_set(args, f"{name}雷达图", 0, 100, False, False))
  1049. )
  1050. k = self.Per_Seeting(args,'Radar')
  1051. for i in data:
  1052. c.add(*i,**self.y_Label(args),color=self.get_Color(),**k)#对i解包,取得name和data 随机颜色
  1053. self.R_Dic[f'{name}雷达图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1054. return c
  1055. def get_Color(self):
  1056. # 随机颜色,雷达图默认非随机颜色
  1057. rgb = [randint(0, 255), randint(0, 255), randint(0, 255)]
  1058. color = '#'
  1059. for a in rgb:
  1060. color += str(hex(a))[-2:].replace('x', '0').upper() # 转换为16进制,upper表示小写(规范化)
  1061. return color
  1062. def to_WordCloud(self,name,text) -> WordCloud:
  1063. get = self.get_Sheet(name)
  1064. data = []
  1065. for i in get.iterrows(): # 按行迭代
  1066. try:
  1067. data.append([str(i[0]),float(i[1].tolist()[0])])
  1068. except:pass
  1069. args = self.Parsing_Parameters(text)
  1070. c = (
  1071. WordCloud(**self.initSetting(args))
  1072. .add(f"{name}", data, **self.Per_Seeting(args,'WordCloud'))
  1073. .set_global_opts(**self.global_set(args, f"{name}词云", 0, 100, False, False))
  1074. )
  1075. self.R_Dic[f'{name}词云[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1076. return c
  1077. def to_Liquid(self,name,text) -> Liquid:
  1078. get = self.get_Sheet(name)
  1079. data = str(get.iloc[0,0])
  1080. c = data.split('.')
  1081. try:
  1082. data = float(f'0.{c[1]}')
  1083. except:
  1084. data = float(f'0.{c[0]}')
  1085. args = self.Parsing_Parameters(text)
  1086. c = (
  1087. Liquid(**self.initSetting(args))
  1088. .add(f"{name}", [data, data])
  1089. .set_global_opts(title_opts=opts.TitleOpts(title=f"{name}水球图", subtitle="CoTan~数据处理"))
  1090. )
  1091. self.R_Dic[f'{name}水球图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1092. return c
  1093. def to_Gauge(self,name,text) -> Gauge:
  1094. get = self.get_Sheet(name)
  1095. data = float(get.iloc[0,0])
  1096. if data > 100:
  1097. data = str(data/100)
  1098. c = data.split('.')
  1099. try:
  1100. data = float(f'0.{c[1]}')*100
  1101. except:
  1102. data = float(f'0.{data}')*100
  1103. args = self.Parsing_Parameters(text)
  1104. c = (
  1105. Gauge(**self.initSetting(args))
  1106. .add(f"{name}", [(f"{name}", data)])
  1107. .set_global_opts(title_opts=opts.TitleOpts(title=f"{name}仪表图", subtitle="CoTan~数据处理"))
  1108. )
  1109. self.R_Dic[f'{name}仪表图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1110. return c
  1111. def to_Calendar(self,name,text) -> Calendar:
  1112. get = self.get_Sheet(name)
  1113. data = [[] for i in self.get_Column(name,True)]
  1114. x_name = self.get_Column(name,True).tolist()
  1115. y = []
  1116. for i in get.iterrows():
  1117. Date = str(i[0])#时间数据
  1118. q = i[1].tolist()
  1119. for a in range(len(q)):
  1120. try:
  1121. data[a].append([Date,q[a]])
  1122. y.append(float(q[a]))
  1123. except:
  1124. pass
  1125. args = self.Parsing_Parameters(text)
  1126. if y == []:
  1127. y = [0,100]
  1128. args['show_Visual_mapping'] = False # 关闭视觉映射
  1129. c = (
  1130. Calendar(**self.initSetting(args))
  1131. .set_global_opts(**self.global_set(args,f"{name}日历图",min(y),max(y),True))
  1132. )
  1133. for i in range(len(x_name)):
  1134. start_Date = data[i][0][0]
  1135. end_Date = data[i][-1][0]
  1136. c.add(str(x_name[i]), data[i], calendar_opts=opts.CalendarOpts(range_=[start_Date,end_Date]), **self.y_Label(args))
  1137. self.R_Dic[f'{name}日历图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1138. return c
  1139. def to_ThemeRiver(self,name,text) -> ThemeRiver:
  1140. get = self.get_Sheet(name)
  1141. data = []
  1142. x_name = self.get_Column(name,True).tolist()
  1143. y = []
  1144. for i in get.iterrows():
  1145. Date = str(i[0])
  1146. q = i[1].tolist()
  1147. for a in range(len(x_name)):
  1148. try:
  1149. data.append([Date, q[a], x_name[a]])
  1150. y.append(float(q[a]))
  1151. except:
  1152. pass
  1153. args = self.Parsing_Parameters(text)
  1154. if y == []:
  1155. y = [0,100]
  1156. args['show_Visual_mapping'] = False # 关闭视觉映射
  1157. c = (
  1158. ThemeRiver(**self.initSetting(args))
  1159. .add(x_name,data,singleaxis_opts=opts.SingleAxisOpts(type_=args['x_type'],pos_bottom="10%"))#抑制大小
  1160. .set_global_opts(**self.global_set(args,f"{name}河流图",min(y),max(y),True,False))
  1161. )
  1162. self.R_Dic[f'{name}河流图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1163. return c
  1164. def to_Sunburst(self,name,text) -> Sunburst:
  1165. get = self.get_Sheet(name)
  1166. def Done(Iter, name):
  1167. k = {'name': name, 'children': []}
  1168. v = 0
  1169. for i in Iter:
  1170. content = Iter[i]
  1171. if isinstance(content, dict):
  1172. new_C = Done(content, str(i))
  1173. v += new_C['value']
  1174. k['children'].append(new_C)
  1175. else:
  1176. try:
  1177. q = float(content)
  1178. except:
  1179. q = len(str(content))
  1180. v += q
  1181. k['children'].append({'name': f'{i}={content}', 'value': q})
  1182. k['value'] = v
  1183. return k
  1184. data = Done(get.to_dict(),name)['children']
  1185. args = self.Parsing_Parameters(text)
  1186. c = (
  1187. Sunburst()
  1188. .add(series_name=f'{name}', data_pair=data, radius=[abs(args['Size']-10), "90%"])
  1189. .set_global_opts(**self.global_set(args, f"{name}旭日图", 0, 100, False, False))
  1190. .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}"))
  1191. )
  1192. self.R_Dic[f'{name}旭日图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1193. return c
  1194. def to_Tree(self,name,text) -> Tree:
  1195. get = self.get_Sheet(name)
  1196. def Done(Iter, name):
  1197. k = {'name': name, 'children': []}
  1198. for i in Iter:
  1199. content = Iter[i]
  1200. if isinstance(content, dict):
  1201. new_C = Done(content, str(i))
  1202. k['children'].append(new_C)
  1203. else:
  1204. k['children'].append({'name': f'{i}', 'children': [{'name': f'{content}'}]})
  1205. return k
  1206. data = [Done(get.to_dict(),name)]
  1207. args = self.Parsing_Parameters(text)
  1208. c = (
  1209. Tree()
  1210. .add(f"{name}", data)
  1211. .set_global_opts(**self.global_set(args, f"{name}树状图", 0, 100, False, False))
  1212. )
  1213. self.R_Dic[f'{name}树状图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1214. return c
  1215. def to_TreeMap(self,name,text) -> TreeMap:
  1216. get = self.get_Sheet(name)
  1217. def Done(Iter, name):
  1218. k = {'name': name, 'children': []}
  1219. v = 0
  1220. for i in Iter:
  1221. content = Iter[i]
  1222. if isinstance(content, dict):
  1223. new_C = Done(content, str(i))
  1224. v += new_C['value']
  1225. k['children'].append(new_C)
  1226. else:
  1227. try:
  1228. q = float(content)
  1229. except:
  1230. q = len(str(content))
  1231. v += q
  1232. k['children'].append({'name': f'{i}={content}', 'value': q})
  1233. k['value'] = v
  1234. return k
  1235. data = Done(get.to_dict(),name)['children']
  1236. args = self.Parsing_Parameters(text)
  1237. c = (
  1238. TreeMap()
  1239. .add(f"{name}", data, label_opts=opts.LabelOpts(is_show=True, position='inside'))
  1240. .set_global_opts(**self.global_set(args, f"{name}矩形树图", 0, 100, False, False))
  1241. )
  1242. self.R_Dic[f'{name}矩形树图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1243. return c
  1244. def to_ScatterGeo(self,name,text) -> Geo:
  1245. get = self.get_Sheet(name)
  1246. column = self.get_Column(name,True).tolist()
  1247. data_Type = ["scatter" for _ in column]
  1248. data = [[] for _ in column]
  1249. y = []
  1250. for i in get.iterrows(): # 按行迭代
  1251. map = str(i[0])
  1252. q = i[1].tolist()
  1253. for a in range(len(q)):
  1254. try:
  1255. v = float(q[a])
  1256. y.append(v)
  1257. except:
  1258. v = str(q[a])
  1259. try:
  1260. if v[:5] == '[##S]':
  1261. #特效图
  1262. v = float(v[5:])
  1263. y.append(v)
  1264. column.append(column[a])
  1265. data_Type.append(GeoType.EFFECT_SCATTER)
  1266. data.append([])
  1267. a = -1
  1268. elif v[:5] == '[##H]':
  1269. # 特效图
  1270. v = float(v[5:])
  1271. y.append(v)
  1272. column.append(column[a])
  1273. data_Type.append(GeoType.HEATMAP)
  1274. data.append([])
  1275. a = -1
  1276. else:raise Exception
  1277. except:
  1278. data_Type[a] = GeoType.LINES#当前变为Line
  1279. data[a].append((map, v))
  1280. args = self.Parsing_Parameters(text)
  1281. args['show_Visual_mapping'] = True#必须视觉映射
  1282. if y == []:y = [0,100]
  1283. if args['is_Dark']:
  1284. g = {'itemstyle_opts':opts.ItemStyleOpts(color="#323c48", border_color="#111")}
  1285. else:
  1286. g = {}
  1287. c = (
  1288. Geo()
  1289. .add_schema(
  1290. maptype=str(args['Map']),**g
  1291. )
  1292. .set_global_opts(**self.global_set(args, f"{name}Geo点地图", min(y), max(y), False))#必须要有视觉映射(否则会显示奇怪的数据)
  1293. )
  1294. for i in range(len(data)):
  1295. if data_Type[i] != GeoType.LINES:
  1296. ka = dict(symbol=args['Symbol'],symbol_size=args['Size'],color='#1E90FF' if args['is_Dark'] else '#0000FF')
  1297. else:
  1298. ka = dict(symbol=SymbolType.ARROW, symbol_size=6,effect_opts=opts.EffectOpts(symbol=SymbolType.ARROW, symbol_size=6, color="blue"),linestyle_opts=opts.LineStyleOpts(curve=0.2,color='#FFF8DC' if args['is_Dark'] else '#000000'))
  1299. c.add(f'{column[i]}',data[i],type_=data_Type[i],**ka)
  1300. c.set_series_opts(label_opts=opts.LabelOpts(is_show=False)) # 不显示数据,必须放在add后面生效
  1301. self.R_Dic[f'{name}Geo点地图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1302. return c
  1303. def to_Map(self,name,text) -> Map:
  1304. get = self.get_Sheet(name)
  1305. column = self.get_Column(name,True).tolist()
  1306. data = [[] for _ in column]
  1307. y = []
  1308. for i in get.iterrows(): # 按行迭代
  1309. map = str(i[0])
  1310. q = i[1].tolist()
  1311. for a in range(len(q)):
  1312. try:
  1313. v = float(q[a])
  1314. y.append(v)
  1315. data[a].append((map, v))
  1316. except:
  1317. pass
  1318. args = self.Parsing_Parameters(text)
  1319. args['show_Visual_mapping'] = True#必须视觉映射
  1320. if y == []:y = [0,100]
  1321. if args['map_Type'] == 'GLOBE':
  1322. Func = MapGlobe
  1323. else:
  1324. Func = Map
  1325. c = Func().set_global_opts(**self.global_set(args, f"{name}Map地图", min(y), max(y), False))#必须要有视觉映射(否则会显示奇怪的数据)
  1326. for i in range(len(data)):
  1327. c.add(f'{column[i]}',data[i],str(args['Map']),is_map_symbol_show=args['show_Map_Symbol'],symbol=args['Symbol'],**self.y_Label(args))
  1328. self.R_Dic[f'{name}Map地图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1329. return c
  1330. def to_Geo(self,name,text) -> Geo:
  1331. get = self.get_Sheet(name)
  1332. column = self.get_Column(name,True).tolist()
  1333. index = self.get_Index(name,True).tolist()
  1334. args = self.Parsing_Parameters(text)
  1335. args['show_Visual_mapping'] = True # 必须视觉映射
  1336. if args['is_Dark']:
  1337. g = {'itemstyle_opts':opts.ItemStyleOpts(color="#323c48", border_color="#111")}
  1338. else:
  1339. g = {}
  1340. c = (
  1341. Geo()
  1342. .add_schema(maptype=str(args['Map']),**g)
  1343. )
  1344. m = []
  1345. for y in column: # 维度
  1346. for x in index: # 精度
  1347. value = get.loc[x, y]
  1348. try:
  1349. v = float(value) # 数值
  1350. type_ = args['Geo_Type']
  1351. except:
  1352. try:
  1353. q = str(value)
  1354. v = float(value[5:])
  1355. if q[:5] == '[##S]':#点图
  1356. type_ = GeoType.SCATTER
  1357. elif q[:5] == '[##E]':#带点特效
  1358. type_ = GeoType.EFFECT_SCATTER
  1359. else:#画线
  1360. v = q.split(';')
  1361. c.add_coordinate(name=f'({v[0]},{v[1]})', longitude=float(v[0]), latitude=float(v[1]))
  1362. c.add_coordinate(name=f'({x},{y})', longitude=float(x), latitude=float(y))
  1363. c.add(f'{name}', [[f'({x},{y})',f'({v[0]},{v[1]})']], type_=GeoType.LINES,
  1364. effect_opts=opts.EffectOpts(symbol=SymbolType.ARROW, symbol_size=6, color="blue"),
  1365. linestyle_opts=opts.LineStyleOpts(curve=0.2, color='#FFF8DC' if args[
  1366. 'is_Dark'] else '#000000', ))
  1367. c.add(f'{name}_XY', [[f'({x},{y})',5],[f'({v[0]},{v[1]})',5]], type_=GeoType.EFFECT_SCATTER,
  1368. color='#1E90FF' if args['is_Dark'] else '#0000FF', )
  1369. raise Exception #continue
  1370. except:
  1371. continue
  1372. try:
  1373. c.add_coordinate(name=f'({x},{y})', longitude=float(x), latitude=float(y))
  1374. c.add(f'{name}', [[f'({x},{y})', v]],type_=type_,symbol=args['Symbol'],symbol_size=args['Size'])
  1375. if type_ == GeoType.HEATMAP:
  1376. c.add(f'{name}_XY', [[f'({x},{y})', v]], type_='scatter',
  1377. color='#1E90FF' if args['is_Dark'] else '#0000FF',)
  1378. m.append(v)
  1379. except:pass
  1380. if m == []:m = [0,100]
  1381. c.set_series_opts(label_opts=opts.LabelOpts(is_show=False))#不显示
  1382. c.set_global_opts(**self.global_set(args, f"{name}Geo地图", min(m), max(m), False))
  1383. self.R_Dic[f'{name}Geo地图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1384. return c
  1385. def to_Bar3d(self,name,text) -> Bar3D:
  1386. get = self.get_Sheet(name)
  1387. x = self.get_Column(name, True).tolist() # 图的x轴,下侧,列名
  1388. y = self.get_Index(name, True).tolist() # 图的y轴,左侧,行名
  1389. value_list = []
  1390. q = []
  1391. for c in range(len(x)): # c-列,r-行
  1392. for r in range(len(y)):
  1393. try:
  1394. v = eval(f'get.iloc[{r},{c}]') # 先行后列
  1395. value_list.append([c, r, v])
  1396. q.append(float(v))
  1397. except:
  1398. pass
  1399. args = self.Parsing_Parameters(text)
  1400. if q == []:
  1401. q = [0,100]
  1402. args['show_Visual_mapping'] = False # 关闭视觉映射
  1403. c = (
  1404. Bar3D(**self.initSetting(args))
  1405. .add(f"{name}",value_list,
  1406. xaxis3d_opts=opts.Axis3DOpts(list(map(str,x)), type_=args["x_type"]),
  1407. yaxis3d_opts=opts.Axis3DOpts(list(map(str,y)), type_=args["y_type"]),
  1408. zaxis3d_opts=opts.Axis3DOpts(type_=args["z_type"]),
  1409. )
  1410. .set_global_opts(**self.global_set(args,f"{name}3D柱状图",min(q),max(q),True),
  1411. ))
  1412. if args['bar_Stacking']:c.set_series_opts(**{"stack": "stack"})#层叠
  1413. self.R_Dic[f'{name}3D柱状图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1414. return c
  1415. def to_Scatter3D(self,name,text) -> Scatter3D:
  1416. get = self.get_Sheet(name)
  1417. x = self.get_Column(name, True).tolist() # 图的x轴,下侧,列名
  1418. y = self.get_Index(name, True).tolist() # 图的y轴,左侧,行名
  1419. value_list = []
  1420. q = []
  1421. for c in range(len(x)): # c-列,r-行
  1422. for r in range(len(y)):
  1423. try:
  1424. v = eval(f'get.iloc[{r},{c}]') # 先行后列
  1425. value_list.append([c, r, v])
  1426. q.append(float(v))
  1427. except:
  1428. pass
  1429. args = self.Parsing_Parameters(text)
  1430. if q == []:
  1431. q = [0,100]
  1432. args['show_Visual_mapping'] = False # 关闭视觉映射
  1433. c = (
  1434. Scatter3D(**self.initSetting(args))
  1435. .add(f"{name}",value_list,
  1436. xaxis3d_opts=opts.Axis3DOpts(list(map(str, x)), type_=args["x_type"]),
  1437. yaxis3d_opts=opts.Axis3DOpts(list(map(str, y)), type_=args["y_type"]),
  1438. zaxis3d_opts=opts.Axis3DOpts(type_=args["z_type"]),
  1439. )
  1440. .set_global_opts(**self.global_set(args,f"{name}3D散点图",min(q),max(q),True))
  1441. )
  1442. self.R_Dic[f'{name}3D散点图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1443. return c
  1444. def to_Line3D(self,name,text) -> Line3D:
  1445. get = self.get_Sheet(name)
  1446. x = self.get_Column(name, True).tolist() # 图的x轴,下侧,列名
  1447. y = self.get_Index(name, True).tolist() # 图的y轴,左侧,行名
  1448. value_list = []
  1449. q = []
  1450. for c in range(len(x)): # c-列,r-行
  1451. for r in range(len(y)):
  1452. try:
  1453. v = eval(f'get.iloc[{r},{c}]') # 先行后列
  1454. value_list.append([c, r, v])
  1455. q.append(float(v))
  1456. except:
  1457. pass
  1458. args = self.Parsing_Parameters(text)
  1459. if q == []:
  1460. q = [0,100]
  1461. args['show_Visual_mapping'] = False # 关闭视觉映射
  1462. c = (
  1463. Line3D(**self.initSetting(args))
  1464. .add(f"{name}",value_list,
  1465. xaxis3d_opts=opts.Axis3DOpts(list(map(str, x)), type_=args["x_type"]),
  1466. yaxis3d_opts=opts.Axis3DOpts(list(map(str, y)), type_=args["y_type"]),
  1467. zaxis3d_opts=opts.Axis3DOpts(type_=args["z_type"]),
  1468. grid3d_opts=opts.Grid3DOpts(width=100, height=100, depth=100),
  1469. )
  1470. .set_global_opts(**self.global_set(args,f"{name}3D折线图",min(q),max(q),True))
  1471. )
  1472. self.R_Dic[f'{name}3D折线图[{len(self.R_Dic)}]{self.get_name(args)}'] = c
  1473. return c
  1474. def Tra_RDic(self):
  1475. self.R_Dic = {}
  1476. def Draw_Page(self, text, Dic) -> Page:
  1477. args = self.Parsing_Parameters(text)
  1478. if args['page_Title'] == '':
  1479. title = 'CoTan_数据处理'
  1480. else:
  1481. title = f"CoTan_数据处理:{args['page_Title']}"
  1482. if args['HTML_Type'] == 1:
  1483. page = Page(page_title=title, layout=Page.DraggablePageLayout)
  1484. page.add(*self.R_Dic.values())
  1485. elif args['HTML_Type'] == 2:
  1486. page = Page(page_title=title, layout=Page.SimplePageLayout)
  1487. page.add(*self.R_Dic.values())
  1488. else:
  1489. page = Tab(page_title=title)
  1490. for i in self.R_Dic:
  1491. page.add(self.R_Dic[i], i)
  1492. page.render(Dic)
  1493. return Dic
  1494. def Overlap(self, down, up):
  1495. Over_Down = self.R_Dic[down]
  1496. Over_Up = self.R_Dic[up]
  1497. Over_Down.overlap(Over_Up)
  1498. return Over_Down
  1499. class Machine_Learner(Draw):#数据处理者
  1500. def __init__(self,*args, **kwargs):
  1501. super().__init__(*args, **kwargs)
  1502. self.Learner = {}#记录机器
  1503. self.Learn_Dic = {'Line':(LinearRegression,()),
  1504. 'Ridge':(Ridge,('alpha','max_iter',)),
  1505. 'Lasso':(Lasso,('alpha','max_iter',)),
  1506. 'LogisticRegression':(LogisticRegression,('C')),
  1507. 'Knn':(KNeighborsClassifier,('n_neighbors',)),
  1508. 'Knn_class': (KNeighborsRegressor, ('n_neighbors',)),
  1509. }
  1510. self.Learner_Type = {}#记录机器的类型
  1511. def DecisionTreeClassifier(self, name):#特征提取
  1512. get = self.get_Sheet(name)
  1513. Dver = DictVectorizer()
  1514. get_Dic = get.to_dict(orient='records')
  1515. new = Dver.fit_transform(get_Dic).toarray()
  1516. Dec = pd.DataFrame(new, columns=Dver.feature_names_)
  1517. self.Add_Form(Dec,f'{name}:特征')
  1518. return Dec
  1519. def p_Args(self,Text):#解析参数
  1520. args = {}
  1521. args_use = {}
  1522. #输入数据
  1523. exec(Text,args)
  1524. #处理数据
  1525. args_use['alpha'] = float(args.get('alpha',1.0))#L1和L2正则化用
  1526. args_use['C'] = float(args.get('C', 1.0)) # L1和L2正则化用
  1527. args_use['max_iter'] = int(args.get('max_iter', 1000)) # L1和L2正则化用
  1528. args_use['n_neighbors'] = int(args.get('K_knn', 5))#knn邻居数 (命名不同)
  1529. args_use['nDim_2'] = bool(args.get('nDim_2', True)) # 数据是否降维
  1530. return args_use
  1531. def Add_Learner(self,Learner,Text=''):
  1532. get,args_Tuple = self.Learn_Dic[Learner]
  1533. name = f'Le[{len(self.Learner)}]{Learner}'
  1534. #参数调节
  1535. args_use = self.p_Args(Text)
  1536. args = {}
  1537. for i in args_Tuple:
  1538. args[i] = args_use[i]
  1539. #生成学习器
  1540. self.Learner[name] = get(**args)
  1541. self.Learner_Type[name] = Learner
  1542. def Return_Learner(self):
  1543. return self.Learner.copy()
  1544. def get_Learner(self,name):
  1545. return self.Learner[name]
  1546. def get_Learner_Type(self,name):
  1547. return self.Learner_Type[name]
  1548. def Fit(self,name,Learnner,Text='',**kwargs):
  1549. Type = self.get_Learner_Type(Learnner)
  1550. args_use = self.p_Args(Text)
  1551. if Type in ('Line','Ridge','Lasso','LogisticRegression','Knn','Knn_class'):
  1552. return self.Fit_Simp(name,Learnner,Down_Ndim=args_use['nDim_2'],**kwargs)
  1553. def Fit_Simp(self,name,Learner,Score_Only=False,Down_Ndim=True,split=0.3,**kwargs):#Score_Only表示仅评分 Fit_Simp 是普遍类操作
  1554. get = self.get_Sheet(name)
  1555. x = get.to_numpy()
  1556. y = self.get_Index(name,True)#获取y值(用index作为y)
  1557. if Down_Ndim or x.ndim == 1:#执行降维处理(也包括升维,ravel让一切变成一维度,包括数字)
  1558. a = x
  1559. x = []
  1560. for i in a:
  1561. try:
  1562. c = i.np.ravel(a[i], 'C')
  1563. x.append(c)
  1564. except:
  1565. x.append(i)
  1566. x = np.array(x)
  1567. model = self.get_Learner(Learner)
  1568. if not Score_Only:#只计算得分,全部数据用于测试
  1569. train_x,test_x,train_y,test_y = train_test_split(x,y,test_size=split)
  1570. model.fit(train_x,train_y)
  1571. train_Score = model.score(train_x, train_y)
  1572. test_Score = model.score(test_x, test_y)
  1573. return train_Score,test_Score
  1574. test_Score = model.score(x, y)
  1575. return 0, test_Score
  1576. def Predict(self,name,Learner,Text='',**kwargs):
  1577. Type = self.get_Learner_Type(Learner)
  1578. args_use = self.p_Args(Text)
  1579. if Type in ('Line','Ridge','Lasso','LogisticRegression','Knn','Knn_class'):
  1580. return self.Predict_Simp(name,Learner,Down_Ndim=args_use['nDim_2'],**kwargs)
  1581. def Predict_Simp(self,name,Learner,Down_Ndim=True,**kwargs):
  1582. get = self.get_Sheet(name)
  1583. column = self.get_Column(name,True)
  1584. x = get.to_numpy()
  1585. if Down_Ndim or x.ndim == 1:#执行降维处理(也包括升维,ravel让一切变成一维度,包括数字)
  1586. a = x
  1587. x = []
  1588. for i in a:
  1589. try:
  1590. c = i.np.ravel(a[i], 'C')
  1591. x.append(c)
  1592. except:
  1593. x.append(i)
  1594. x = np.array(x)
  1595. model = self.get_Learner(Learner)
  1596. answer = model.predict(x)
  1597. data = pd.DataFrame(x,index=answer,columns=column)
  1598. self.Add_Form(data,f'{name}:预测')
  1599. return data
  1600. def Show_Args(self,Learner,new=False):#显示参数
  1601. learner = self.get_Learner(Learner)
  1602. learner_Type = self.get_Learner_Type(Learner)
  1603. if learner_Type in ('Ridge','Lasso'):
  1604. Alpha = learner.alpha#阿尔法
  1605. w = learner.coef_.tolist()#w系数
  1606. b = learner.intercept_#截距
  1607. max_iter = learner.max_iter
  1608. w_name = [f'权重:W[{i}]' for i in range(len(w))]
  1609. index = ['阿尔法:Alpha'] + w_name + ['截距:b','最大迭代数']
  1610. data = [Alpha] + w + [b] + [max_iter]
  1611. #文档
  1612. doc = (f'阿尔法:alpha = {Alpha}\n\n权重:\nw = \n{pd.DataFrame(w)}\n\n截距:b = {b}\n\n最大迭代数:{max_iter}\n\n\nEND')
  1613. data = pd.DataFrame(data,index=index)
  1614. elif learner_Type in ('Line'):
  1615. w = learner.coef_.tolist() # w系数
  1616. b = learner.intercept_
  1617. index = [f'权重:W[{i}]' for i in range(len(w))] + ['截距:b']
  1618. data = w + [b] # 截距
  1619. #文档
  1620. doc = (f'权重:w = \n{pd.DataFrame(w)}\n\n截距:b = {b}\n\n\nEND')
  1621. data = pd.DataFrame(data, index=index)
  1622. elif learner_Type in ('Knn'):#Knn_class
  1623. classes = learner.classes_.tolist()#分类
  1624. n = learner.n_neighbors#个数
  1625. p = {1:'曼哈顿距离',2:'欧几里得距离'}.get(learner.p)
  1626. index = [f'类目[{i}]' for i in range(len(classes))] + ['邻居个数','距离公式']
  1627. data = classes + [n,p]
  1628. doc = f'分类类目:\n{pd.DataFrame(classes)}\n\n邻居个数:{n}\n\n计算距离的方式:{p}\n\n\nEND'
  1629. data = pd.DataFrame(data,index=index)
  1630. elif learner_Type in ('Knn_class'):
  1631. n = learner.n_neighbors#个数
  1632. p = {1:'曼哈顿距离',2:'欧几里得距离'}.get(learner.p)
  1633. index = ['邻居个数','距离公式']
  1634. data = [n,p]
  1635. doc = f'邻居个数:{n}\n\n计算距离的方式:{p}\n\n\nEND'
  1636. data = pd.DataFrame(data,index=index)
  1637. elif learner_Type in ('LogisticRegression',):
  1638. classes = learner.classes_.tolist()#分类
  1639. w = learner.coef_.tolist() # w系数
  1640. b = learner.intercept_
  1641. C = learner.C
  1642. index = [f'类目[{i}]' for i in range(len(classes))] + [f'权重:W[{j}][{i}]' for i in range(len(w)) for j in range(len(w[i]))] + [f'截距:b[{i}]' for i in range(len(b))]+['C']
  1643. data = classes + [j for i in w for j in i] + [i for i in b] + [C]
  1644. doc = f'分类类目:\n{pd.DataFrame(classes)}\n\n权重:w = \n{pd.DataFrame(w)}\n\n截距:b = {b}\n\nC={C}\n\n\n'
  1645. data = pd.DataFrame(data,index=index)
  1646. else:
  1647. return '',[]
  1648. if new:
  1649. self.Add_Form(data,f'{Learner}:属性')
  1650. return doc,data
  1651. def Del_Leaner(self,Leaner):
  1652. del self.Learner[Leaner]
  1653. del self.Learner_Type[Leaner]