天天看點

Python可視化:中國環保股上市公司市值Top20強

制作近10年期間,環保闆塊市值最高的20隻股票動态變化,需要獲得各隻股票在不同年份的市值。擷取特定股票的市值可以利用

pro.daily_basic

接口擷取到每日的市值,然後利用Resample函數獲得年均市值。但擷取環保闆塊所有幾十隻股票的資料,用手動輸入股票代碼就不是很友善,此時,可以利用該包另外一個接口

ts.get_stock_basics()接口

擷取所有股票基本資料,該接口能夠傳回股票代碼、行業類别等資料。兩個接口合二為一就可以提取出所需的資料,下面開始詳細實作步驟。

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支。其中,選中的列為每日市值(萬元)。下面就可以根據日期、市值得到各隻股票每年的市值均值,然後繪制股票動态表。

Python可視化:中國環保股上市公司市值Top20強

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

可繪制出動态可視化表格,見下面視訊。可以看到前幾年市值龍頭由東方園林、碧桂園輪流坐莊,近兩年三聚環保強勢崛起,市值增長迅猛,躍居頭名。

Python可視化:中國環保股上市公司市值Top20強

本文僅對比了環保股企業的市值變化,你還可以分析網際網路股、金融股等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萬開發者關注。

原文釋出時間為:2018-10-25

本文作者:蘇克1900

本文來自雲栖社群合作夥伴“

Python中文社群

”,了解相關資訊可以關注“

”。