利用Python視覺化來檢視中國環保股上市公司!排名第一的居然是?
1. 提取所有股票程式碼
1import tushare as ts
2# 獲取所有股票列表
3data = ts.get_stock_basics()
4print(data.head())
5# 返回資料如下,所有列值可以參考:http://tushare.org/fundamental.html
6 name industry area pe outstanding totals totalAssets
7code
8002936 N鄭銀 銀行 河南 8.27 6.00 59.22 44363604.00
9600856 中天能源 供氣供熱 吉林 21.28 13.43 13.67 1712831.63
10300021 大禹節水 農業綜合 甘肅 35.27 6.48 7.97 359294.91
11603111 康尼機電 運輸裝置 江蘇 0.00 7.38 9.93 734670.69
12000498 山東路橋 建築施工 山東 19.52 4.41 11.20 1926262.38
可以看到,index是股票程式碼,name股票名稱,industry是行業分類。我們需要獲取環保類(可以獲取任意行業類別,也可以全部獲取所有股票,為了後期資料提取量耗時短一些,所以選擇提取環保類股票)的股票程式碼和股票名稱,程式碼如下:
1data = data[data.industry =='環境保護']
2print(data.head()) #返回的環保股資料
3print('環保股股票數量為':len(data.industry)) #計算環保股股票數量
4結果如下:
5 name industry area pe outstanding totals totalAssets
6code
7300056 三維絲 環境保護 福建 0.00 2.37 3.85 266673.63
8002549 凱美特氣 環境保護 湖南 34.44 6.20 6.24 122630.13
9300422 博世科 環境保護 廣西 19.22 2.64 3.56 509822.44
10601330 綠色動力 環境保護 深圳 59.83 1.16 11.61 784969.25
11000820 神霧節能 環境保護 遼寧 0.00 2.88 6.37 284674.34
12環保股股票數量為: 66
可以看到,環境保護股一共有66只,下面我們將用這66只股票的程式碼和名稱,輸入到pro.daily_basic()介面中,獲取每隻股票的每日資料,其中包括每日市值。時間期限從2009年1月1日至2018年9月10日,共10年的逐日資料。
2. 提股票每日市值
每日基本指標的資料介面:https://tushare.pro/document/2?doc_id=32
1pro = ts.pro_api()
2pro.daily_basic(ts_code='', trade_date='',start_date = '',end_date = '')
3# ts_code是股票程式碼,格式為000002.SZ,可以為一隻股票,也可以是列表組成的多支股票
4# 後面三個是交易日期,可以為固定日期,也可以為一個時期,格式'20180919'
該介面股票程式碼的格式是000002.SZ,而上面股票程式碼格式是:000002,沒有帶字尾.SZ,由此需要新增上,然後就可獲取每隻股票近10年的逐日市值資料。
1data['code2'] = data.index
2# apply方法新增.SZ字尾
3data['code2'] = data['code2'].apply(lambda i:i+'.SZ')
4data = data.set_index(['code2'])
5# 將code和name轉為dict,因為我們只需要表格中的程式碼和名稱列
6data = data['name']
7data = data.to_dict()
8
9# print(data) #測試返回的環保股字典資料 ok
10{'300056.SZ': '三維絲', '002549.SZ': '凱美特氣', '300422.SZ': '博世科', '601330.SZ': '綠色動力', '000820.SZ': '神霧節能', '300072.SZ': '三聚環保', '300055.SZ': '萬邦達', '002717.SZ': '嶺南股份', '300070.SZ': '碧水源', '000504.SZ': '南華生物', '300203.SZ': '聚光科技', '002672.SZ': '東江環保', '000967.SZ': '盈峰環境', '002322.SZ': '理工環科', '300272.SZ': '開能健康', '300495.SZ': '美尚生態', '603717.SZ': '天域生態', '300266.SZ': '興源環境', '603126.SZ': '中材節能', '002200.SZ': '雲投生態', '300385.SZ': '雪浪環境', '603200.SZ': '上海洗霸', '000826.SZ': '啟迪桑德', '300262.SZ': '巴安水務', '002887.SZ': '綠茵生態', '603568.SZ': '偉明環保', '300631.SZ': '久吾高科', '002616.SZ': '長青集團', '300156.SZ': '神霧環保', '000920.SZ': '南方匯通', '600008.SZ': '首創股份', '601200.SZ': '上海環境', '603955.SZ': '大千生態', '603177.SZ': '德創環保', '600481.SZ': '雙良節能', '300190.SZ': '維爾利', '603588.SZ': '高能環境', '002034.SZ': '旺能環境', '603817.SZ': '海峽環保', '002499.SZ': '科林環保', '603822.SZ': '嘉澳環保', '300664.SZ': '鵬鷂環保', '300332.SZ': '天壕環境', '600526.SZ': '菲達環保', '600874.SZ': '創業環保', '600292.SZ': '遠達環保', '603903.SZ': '中持股份', '300172.SZ': '中電環保', '000544.SZ': '中原環保', '300692.SZ': '中環環保', '600388.SZ': '龍淨環保', '300425.SZ': '環能科技', '300388.SZ': '國禎環保', '300362.SZ': '天翔環境', '300197.SZ': '鐵漢生態', '300187.SZ': '永清環保', '300090.SZ': '盛運環保', '002573.SZ': '清新環境', '000035.SZ': '中國天楹', '603797.SZ': '聯泰環保', '603603.SZ': '博天環境', '300137.SZ': '先河環保', '300355.SZ': '蒙草生態', '300152.SZ': '科融環境', '002658.SZ': '雪迪龍', '600217.SZ': '中再資環'}
可以看到,很完整地顯示了環保股的股票程式碼和名稱,下面通過for迴圈即可獲取每日資料。為了方便,將上式程式碼命名為一個函式get_code(),return data 為上面的dict。
3. 提取環保股公司資料
1ts_codes = get_code()
2start = '20090101'
3end = '201809010'
4for key,value in ts_codes.items():
5 data = pro.daily_basic(ts_code=key, start_date=start, end_date=end) # 獲取每隻股票時間段資料
6 # 新增程式碼列和名稱列
7 # 替換掉末尾的.SZ,regex設定為true才行
8 data['code'] = data['ts_code'].replace('.SZ','',regex = True)
9 data['name'] = value
10 # 儲存結果
11 data.to_csv('environment.csv',mode='a',encoding = 'utf_8_sig',index = False,header = 0)
12 print('資料提取完畢')
表格結果如下,66只股票10年一共產生了75933行資料。如果提前全部3000多家股票的資料,那麼資料量會達到幾百萬行,量太大,所以這裡僅提取了66支。其中,選中的列為每日市值(萬元)。下面就可以根據日期、市值得到各只股票每年的市值均值,然後繪製股票動態表。
進群:548377875 即可獲取大量的學習資料以及從入門拿到專案實戰的PDF哦!希望早日拿到高薪!
4. 繪製Top20強動態表
首先讀取上面的表格,獲取DataFrame資訊:
1df = pd.read_csv('environment.csv',encoding = 'utf-8',converters = {'code':str})
2# converters = {'code':str} 將數字前面不顯示的0轉為str顯示
3print(df.info())
4
5Data columns (total 17 columns):
6ts_code 75932 non-null object
7trade_date 75932 non-null int64
8close 75932 non-null float64
9turnover_rate 75932 non-null float64
10volume_ratio 0 non-null float64
11pe 70861 non-null float64
12e_ttm 69254 non-null float64
13pb 73713 non-null float64
14ps 75932 non-null float64
15ps_ttm 75840 non-null float64
16total_share 75932 non-null float64
17float_share 75932 non-null float64
18free_share 75932 non-null float64
19total_mv 75932 non-null float64
20circ_mv 75932 non-null float64
21code 75932 non-null int64
22name 75932 non-null object
23dtypes: float64(13), int64(2), object(2)
可以看到trade_date交易日期是整形,需將交易日期先轉換為字元型再轉換為datetime日期型。
1from datetime import datetime
2# trade_date是int型,需轉為字元型
3df['trade_date'] = df['trade_date'].apply(str)
4# 或者
5# df['trade_date'] = df['trade_date'].astype(str)
6# 將object轉為datatime
7df['trade_date'] = pd.to_datetime(df['trade_date'],format = '%Y%m%d',errors = 'ignore') #errors忽略無法轉換的資料,不然會報錯
8# 結果如下:
9Data columns (total 17 columns):
10ts_code 75932 non-null object
11trade_date 75932 non-null datetime64[ns]
12close 75932 non-null float64
13turnover_rate 75932 non-null float64
14volume_ratio 0 non-null float64
15pe 70861 non-null float64
16e_ttm 69254 non-null float64
17pb 73713 non-null float64
18ps 75932 non-null float64
19ps_ttm 75840 non-null float64
20total_share 75932 non-null float64
21float_share 75932 non-null float64
22free_share 75932 non-null float64
23total_mv 75932 non-null float64
24circ_mv 75932 non-null float64
25code 75932 non-null int64
26name 75932 non-null object
接著再將市值格式改變為億元。
1# 設定總市值數字格式由萬元變為億元
2df['total_mv'] = (df['total_mv']/10000)
3# 保留四列,並將交易日期設為index
4df = df[['ts_code','trade_date','total_mv','name']]
5df = df.set_index('trade_date')
6print(df.head())
7# 結果如下:
8 ts_code total_mv name
9trade_date
102018-08-30 300090.SZ 36.034715 盛運環保
112018-08-29 300090.SZ 38.014644 盛運環保
122018-08-28 300090.SZ 39.202602 盛運環保
132018-08-27 300090.SZ 40.126569 盛運環保
142018-08-24 300090.SZ 38.938611 盛運環保
接下來,求出每隻股票每年的市值平均值:
1# 求平均市值時需切片同一股票,這裡股票名稱切片賦值為value變數,也就是dict字典裡66只股票名稱
2df = df[df.name == value]
3# 不能用query方法,會報錯 df = df.query('name == value')
4# resampe按年統計資料
5df = df.resample('AS').mean() #年平均市值
6print(df.head())
7# 結果如下:
8 total_mv code
9trade_date
102009-01-01 25.184678 三維絲
112010-01-01 50.672849 三維絲
122011-01-01 46.488004 三維絲
132012-01-01 39.214508 三維絲
142013-01-01 59.110332 三維絲
15# 再用to_period按年顯示市值資料
16df = df.to_period('A')
17print(df.head())
18# 結果如下:
19 total_mv code
20trade_date
212009 25.184678 三維絲
222010 50.672849 三維絲
232011 46.488004 三維絲
242012 39.214508 三維絲
252013 59.110332 三維絲
經過以上處理,基本就獲得了想要的資料。為了能夠滿足D3.js模板表格條件,再做一點修改:
1# 增加code列
2df['code'] = value
3# 重置index
4df = df.reset_index()
5# 重新命名為d3.js格式
6# 增加一列空type
7df['type'] = ''
8df = df[['code','type','total_mv','trade_date']]
9df.rename(columns = {'code':'name','total_mv':'value','type':'type','trade_date':'date'})
10# df.to_csv('parse_environment.csv',mode='a',encoding = 'utf_8_sig',index = False,float_format = '%.1f',header = 0) # float_format = '%.1f' #設定輸出浮點數格式為1位小數
最終,生成parse_environment.csv檔案如下:
1name type value date
2中國天楹 8.8 2009
3中國天楹 9.8 2010
4中國天楹 15 2011
5中國天楹 18.8 2012
6中國天楹 22.5 2013
7...
8東方園林 177.1 2014
9東方園林 320.5 2015
10東方園林 288.4 2016
11東方園林 481 2017
12東方園林 461.5 2018
可繪製出動態視覺化表格,見下面視訊。可以看到前幾年市值龍頭由東方園林、碧桂園輪流坐莊,近兩年三聚環保強勢崛起,市值增長迅猛,躍居頭名。
本文僅對比了環保股企業的市值變化,你還可以分析網際網路股、金融股等100多種行業的企業市值對比。另外,Tushare包返回的引數還可以做更多其他分析。
文章完整的程式碼如下:
1import pandas as pd
2import tushare as ts
3from datetime import datetime
4import matplotlib.pyplot as plt
5ts.set_token('404ba015bd44c01cf09c8183dcd89bb9b25749057ff72b5f8671b9e6')
6pro = ts.pro_api()
7def get_code():
8 # 所有股票列表
9 data = ts.get_stock_basics()
10 # data = data.query('industry == "環境保護"')
11 # 或者
12 data = data[data.industry =='環境保護']
13 # 提取股票程式碼code並轉化為list
14 data['code2'] = data.index
15 # apply方法新增.SZ字尾
16 data['code2'] = data['code2'].apply(lambda i:i+'.SZ')
17 data = data.set_index(['code2'])
18 # 將code和name轉為dict
19 data = data['name']
20 data = data.to_dict()
21 # 增加東方園林
22 data['002310.SZ'] = '東方園林'
23 # print(data) #測試返回的環保股dict ok
24 return data
25
26def stock(key,start,end,value):
27 data = pro.daily_basic(ts_code=key, start_date=start, end_date=end) # 獲取每隻股票時間段資料
28
29 # 替換掉末尾的.SZ,regex設定為true才行
30 data['code'] = data['ts_code'].replace('.SZ','',regex = True)
31 data['name'] = value
32 # print(data)
33 data.to_csv('environment.csv',mode='a',encoding = 'utf_8_sig',index = False,header = 0)
34
35def parse_code():
36 df = pd.read_csv('environment.csv',encoding = 'utf-8',converters = {'code':str})
37 # converters = {'code':str} 將數字前面不顯示的0轉為str顯示
38 df.columns = ['ts_code','trade_date','close','turnover_rate','volume_ratio','pe','e_ttm','pb','ps','ps_ttm','total_share','float_share','free_share','total_mv','circ_mv', 'code','name']
39 # trade_date是int型,需轉為字元型
40 df['trade_date'] = df['trade_date'].apply(str)
41 # 或者df['trade_date'] = df['trade_date'].astype(str)
42 # 將object轉為datatime
43 df['trade_date'] = pd.to_datetime(df['trade_date'],format = '%Y%m%d',errors = 'ignore') #errors忽略無法轉換的資料,不然會報錯
44 ## 設定總市值數字格式由萬元變為億元
45 df['total_mv'] = (df['total_mv']/10000)
46 # 保留四列,並將交易日期設為index
47 df = df[['ts_code','trade_date','total_mv','name']]
48 df = df.set_index('trade_date')
49
50 df = df[df.name == value]
51 # # 不能用query方法
52 # # df = df.query('name == ')
53 df = df.resample('AS').mean()/10000 #年平均市值
54 df = df.to_period('A')
55 # # 增加code列
56 df['code'] = value
57 # # 重置index
58 df = df.reset_index()
59
60 # 重新命名為d3.js格式
61 # 增加一列空type
62 df['type'] = ''
63 df = df[['code','type','total_mv','trade_date']]
64 df.rename(columns = {'code':'name','total_mv':'value','type':'type','trade_date':'date'})
65 df.to_csv('parse_environment.csv',mode='a',encoding = 'utf_8_sig',index = False,float_format = '%.1f',header = 0)
66 float_format = '%.1f' #設定輸出浮點數格式
67 # print(df)
68 # print(df.info())
69
70def main():
71 # get_code() #提取環保股dict
72 start = '20090101'
73 end = '201809010'
74 ts_codes = get_code()
75 # dict_values轉list
76 keys = list(ts_codes.keys())
77 values = list(ts_codes.values())
78 for key,value in ts_codes.items():
79 stock(key,start,end,value)
80 for value in values:
81 parse_code(value)
82
83if __name__ == '__main__':
84 main()
Python中文社群作為一個去中心化的全球技術社群,以成為全球20萬Python中文開發者的精神部落為願景,目前覆蓋各大主流媒體和協作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業界知名公司和技術社群建立了廣泛的聯絡,擁有來自十多個國家和地區數萬名登記會員,會員來自以公安部、工信部、清華大學、北京大學、北京郵電大學、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機關、科研單位、金融機構以及海內外知名公司,全平臺近20萬開發者關注。