首頁 > 軟體

Python股票資料視覺化程式碼詳解

2022-03-16 13:01:05
import numpy as np
import pandas as pd
from pandas_datareader import data
import datetime as dt

資料準備

'''
獲取國內股票資料的方式是:「股票程式碼」+「對應股市」(港股為.hk,A股為.ss)
例如騰訊是港股是:0700.hk
'''
#字典:6家公司的股票
# gafataDict={'谷歌':'GOOG','亞馬遜':'AMZN','Facebook':'FB', '蘋果':'AAPL','阿里巴巴':'BABA','騰訊':'0700.hk'}
'''
定義函數
函數功能:計算股票漲跌幅=(現在股價-買入價格)/買入價格
輸入引數:column是收盤價這一列的資料
返回資料:漲跌幅
'''
def change(column):
    # 買入價格
    buyPrice=column[0]
    # 現在股價
    curPrice=column[column.size-1]
    priceChange=(curPrice-buyPrice)/buyPrice
    # 判斷股票是上漲還是下跌
    if priceChange>0:
        print('股票累計上漲=',round(priceChange*100,2),'%')
    elif priceChange==0:
        print('股票無變化=',round(priceChange*100,2)*100,'%')
    else:
        print('股票累計下跌=',round(priceChange*100,2)*100,'%')
    # 返回資料
    return priceChange
'''
三星電子
每日股票價位資訊
Open:開盤價
High:最高加
Low:最低價
Close:收盤價
Volume:成交量
因雅虎連線不到,僅以三星作為獲取資料範例
'''
sxDf = data.DataReader('005930', 'naver', start='2021-01-01', end='2022-01-01')
sxDf.head()
 OpenHighLowCloseVolume
Date     
2021-01-048100084400802008300038655276
2021-01-058160083900816008390035335669
2021-01-068330084500821008220042089013
2021-01-078280084200827008290032644642
2021-01-088330090000830008880059013307
sxDf.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 248 entries, 2021-01-04 to 2021-12-30
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   Open    248 non-null    object
 1   High    248 non-null    object
 2   Low     248 non-null    object
 3   Close   248 non-null    object
 4   Volume  248 non-null    object
dtypes: object(5)
memory usage: 11.6+ KB
sxDf.iloc[:,0:4]=sxDf.iloc[:,0:4].astype('float')
sxDf.iloc[:,-1]=sxDf.iloc[:,-1].astype('int')
sxDf.info()
<class 'pandas.core.frame.DataFrame'>DatetimeIndex: 248 entries, 2021-01-04 to 2021-12-30Data columns (total 5 columns): #   Column  Non-Null Count  Dtype  ---  ------  --------------  -----   0   Open    248 non-null    float64 1   High    248 non-null    float64 2   Low     248 non-null    float64 3   Close   248 non-null    float64 4   Volume  248 non-null    int32  dtypes: float64(4), int32(1)memory usage: 10.7 KB<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 248 entries, 2021-01-04 to 2021-12-30
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   Open    248 non-null    float64
 1   High    248 non-null    float64
 2   Low     248 non-null    float64
 3   Close   248 non-null    float64
 4   Volume  248 non-null    int32  
dtypes: float64(4), int32(1)
memory usage: 10.7 KB

阿里巴巴

# 讀取資料
AliDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder阿里巴巴2017年股票資料.xlsx',index_col='Date')
AliDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-22175.839996176.660004175.039993176.289993176.28999312524700
2017-12-26174.550003175.149994171.729996172.330002172.33000212913800
2017-12-27172.289993173.869995171.729996172.970001172.97000110152300
2017-12-28173.039993173.529999171.669998172.300003172.3000039508100
2017-12-29172.279999173.669998171.199997172.429993172.4299939704600
# 檢視基本資訊及資料型別
AliDf.info()
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 251 entries, 2017-01-03 to 2017-12-29
Data columns (total 6 columns):
 #   Column     Non-Null Count  Dtype  
---  ------     --------------  -----  
 0   Open       251 non-null    float64
 1   High       251 non-null    float64
 2   Low        251 non-null    float64
 3   Close      251 non-null    float64
 4   Adj Close  251 non-null    float64
 5   Volume     251 non-null    int64  
dtypes: float64(5), int64(1)
memory usage: 13.7 KB
# 計算漲跌幅
AliChange=change(AliDf['Close'])
股票累計上漲= 94.62 %
'''增加一列累計增長百分比'''
#一開始的股價
Close1=AliDf['Close'][0]
# # .apply(lambda x: format(x, '.2%'))
AliDf['sum_pct_change']=AliDf['Close'].apply(lambda x: (x-Close1)/Close1)
AliDf['sum_pct_change'].tail()
Date
2017-12-22    0.989729
2017-12-26    0.945034
2017-12-27    0.952257
2017-12-28    0.944695
2017-12-29    0.946162
Name: sum_pct_change, dtype: float64

谷歌

# 讀取資料
GoogleDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder谷歌2017年股票資料.xlsx',index_col='Date')
GoogleDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-221061.1099851064.1999511059.4399411060.1199951060.119995755100
2017-12-261058.0699461060.1199951050.1999511056.7399901056.739990760600
2017-12-271057.3900151058.3699951048.0500491049.3699951049.3699951271900
2017-12-281051.5999761054.7500001044.7700201048.1400151048.140015837100
2017-12-291046.7199711049.6999511044.9000241046.4000241046.400024887500
# 計算漲跌幅
GoogleChange=change(GoogleDf['Close'])
股票累計上漲= 33.11 %
'''增加一列累計增長百分比'''
#一開始的股價
Close1=GoogleDf['Close'][0]
# # .apply(lambda x: format(x, '.2%'))
GoogleDf['sum_pct_change']=GoogleDf['Close'].apply(lambda x: (x-Close1)/Close1)
GoogleDf['sum_pct_change'].tail()
Date
2017-12-22    0.348513
2017-12-26    0.344213
2017-12-27    0.334839
2017-12-28    0.333274
2017-12-29    0.331061
Name: sum_pct_change, dtype: float64

蘋果

# 讀取資料
AppleDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder蘋果2017年股票資料.xlsx',index_col='Date')
AppleDf.tail()
OpenHighLowCloseAdj CloseVolume
Date
2017-12-22174.679993175.419998174.500000175.009995174.29936216349400
2017-12-26170.800003171.470001169.679993170.570007169.87739633185500
2017-12-27170.100006170.779999169.710007170.600006169.90727221498200
2017-12-28171.000000171.850006170.479996171.080002170.38531516480200
2017-12-29170.520004170.589996169.220001169.229996168.54283125999900
# 計算漲跌幅
AppleChange=change(AppleDf['Close'])
股票累計上漲= 45.7 %
'''增加一列累計增長百分比'''
#一開始的股價
Close1=AppleDf['Close'][0]
# # .apply(lambda x: format(x, '.2%'))
AppleDf['sum_pct_change']=AppleDf['Close'].apply(lambda x: (x-Close1)/Close1)
AppleDf['sum_pct_change'].tail()
Date
2017-12-22    0.506758
2017-12-26    0.468532
2017-12-27    0.468790
2017-12-28    0.472923
2017-12-29    0.456995
Name: sum_pct_change, dtype: float64

騰訊

# 讀取資料
TencentDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder騰訊2017年股票資料.xlsx',index_col='Date')
TencentDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-22403.799988405.799988400.799988405.799988405.79998816146080
2017-12-27405.799988407.799988401.000000401.200012401.20001216680601
2017-12-28404.000000408.200012402.200012408.200012408.20001211662053
2017-12-29408.000000408.000000403.399994406.000000406.00000016601658
2018-01-02406.000000406.000000406.000000406.000000406.0000000
# 讀取資料
TencentDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder騰訊2017年股票資料.xlsx',index_col='Date')
TencentDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-22403.799988405.799988400.799988405.799988405.79998816146080
2017-12-27405.799988407.799988401.000000401.200012401.20001216680601
2017-12-28404.000000408.200012402.200012408.200012408.20001211662053
2017-12-29408.000000408.000000403.399994406.000000406.00000016601658
2018-01-02406.000000406.000000406.000000406.000000406.0000000
# 計算漲跌幅
TencentChange=change(TencentDf['Close'])
股票累計上漲= 114.36 %
'''增加一列累計增長百分比'''
#一開始的股價
Close1=TencentDf['Close'][0]
# # .apply(lambda x: format(x, '.2%'))
TencentDf['sum_pct_change']=TencentDf['Close'].apply(lambda x: (x-Close1)/Close1)
TencentDf['sum_pct_change'].tail()
Date
2017-12-22    1.142555
2017-12-27    1.118268
2017-12-28    1.155227
2017-12-29    1.143611
2018-01-02    1.143611
Name: sum_pct_change, dtype: float64

亞馬遜

# 讀取資料
AmazonDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled Folder亞馬遜2017年股票資料.xlsx',index_col='Date')
AmazonDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-221172.0799561174.6199951167.8299561168.3599851168.3599851585100
2017-12-261168.3599851178.3199461160.5500491176.7600101176.7600102005200
2017-12-271179.9100341187.2900391175.6099851182.2600101182.2600101867200
2017-12-281189.0000001190.0999761184.3800051186.0999761186.0999761841700
2017-12-291182.3499761184.0000001167.5000001169.4699711169.4699712688400
# 計算漲跌幅
AmazonChange=change(AmazonDf['Close'])
股票累計上漲= 55.17 %
'''增加一列累計增長百分比'''
#一開始的股價
Close1=AmazonDf['Close'][0]
# # .apply(lambda x: format(x, '.2%'))
AmazonDf['sum_pct_change']=AmazonDf['Close'].apply(lambda x: (x-Close1)/Close1)
AmazonDf['sum_pct_change'].tail()
Date
2017-12-22    0.550228
2017-12-26    0.561373
2017-12-27    0.568671
2017-12-28    0.573766
2017-12-29    0.551700
Name: sum_pct_change, dtype: float64

Facebook

# 讀取資料
FacebookDf=pd.read_excel(r'C:UsersEDYDesktop吧哩吧啦學習Untitled FolderFacebook2017年股票資料.xlsx',index_col='Date')
FacebookDf.tail()
 OpenHighLowCloseAdj CloseVolume
Date      
2017-12-22177.139999177.529999176.229996177.199997177.1999978509500
2017-12-26176.630005177.000000174.669998175.990005175.9900058897300
2017-12-27176.550003178.440002176.259995177.619995177.6199959496100
2017-12-28177.949997178.940002177.679993177.919998177.91999812220800
2017-12-29178.000000178.850006176.460007176.460007176.46000710261500
# 計算漲跌幅
FacebookChange=change(FacebookDf['Close'])
股票累計上漲= 51.0 %
'''增加一列每日增長百分比'''
# .pct_change()返回變化百分比,第一行因沒有可對比的,返回Nan,填充為0
FacebookDf['pct_change']=FacebookDf['Close'].pct_change(1).fillna(0)
FacebookDf['pct_change'].head()
Date
2017-01-03    0.000000
2017-01-04    0.015660
2017-01-05    0.016682
2017-01-06    0.022707
2017-01-09    0.012074
Name: pct_change, dtype: float64
'''增加一列累計增長百分比'''
#一開始的股價
Close1=FacebookDf['Close'][0]
# .apply(lambda x: format(x, '.2%'))
FacebookDf['sum_pct_change']=FacebookDf['Close'].apply(lambda x: (x-Close1)/Close1)
FacebookDf['sum_pct_change'].tail()
Date
2017-12-22    0.516344
2017-12-26    0.505990
2017-12-27    0.519938
2017-12-28    0.522506
2017-12-29    0.510012
Name: sum_pct_change, dtype: float64

資料視覺化

import matplotlib.pyplot as plt
# 檢視成交量與股價之間的關係
fig=plt.figure(figsize=(10,5))
AliDf.plot(x='Volume',y='Close',kind='scatter')
plt.xlabel('成交量')
plt.ylabel('股價')
plt.title('成交量與股價之間的關係')
plt.show()
<Figure size 720x360 with 0 Axes>

# 檢視各個引數之間的相關性,與股價與成交量之間呈中度相關
AliDf.corr()
 OpenHighLowCloseAdj CloseVolumesum_pct_change
Open1.0000000.9992810.9987980.9982260.9982260.4246860.998226
High0.9992811.0000000.9987820.9990770.9990770.4324670.999077
Low0.9987980.9987821.0000000.9992490.9992490.4014560.999249
Close0.9982260.9990770.9992491.0000001.0000000.4158011.000000
Adj Close0.9982260.9990770.9992491.0000001.0000000.4158011.000000
Volume0.4246860.4324670.4014560.4158010.4158011.0000000.415801
sum_pct_change0.9982260.9990770.9992491.0000001.0000000.4158011.000000

檢視各個公司的股價平均值

AliDf['Close'].mean()
141.79179260159364
'''資料準備'''
# 計算每家公司的收盤價平均值
Close_mean={'Alibaba':AliDf['Close'].mean(),
            'Google':GoogleDf['Close'].mean(),
            'Apple':AppleDf['Close'].mean(),
            'Tencent':TencentDf['Close'].mean(),
            'Amazon':AmazonDf['Close'].mean(),
            'Facebook':FacebookDf['Close'].mean()}
CloseMeanSer=pd.Series(Close_mean)
CloseMeanSer.sort_values(ascending=False,inplace=True) 
'''繪製柱狀圖'''
# 建立畫板
fig=plt.figure(figsize=(10,5))
# 繪圖
CloseMeanSer.plot(kind='bar')
# 設定x、y軸標籤及標題
plt.xlabel('公司')
plt.ylabel('股價平均值(美元)')
plt.title('2017年各公司股價平均值')
# 設定y周標籤刻度
plt.yticks(np.arange(0,1100,100))
# 顯示y軸網格
plt.grid(True,axis='y')
# 顯示影象
plt.show()

亞馬遜和谷歌的平均股價很高,遠遠超過其他4家,但是僅看平均值並不能代表什麼,下面從分佈和走勢方面檢視

檢視各公司股價分佈情況

'''資料準備'''
# 將6家公司的收盤價整合到一起
CloseCollectDf=pd.concat([AliDf['Close'],
                          GoogleDf['Close'],
                          AppleDf['Close'],
                          TencentDf['Close'],
                          AmazonDf['Close'],
                          FacebookDf['Close']],axis=1)
CloseCollectDf.columns=['Alibaba','Google','Apple','Tencent','Amazon','Facebook']
'''繪製箱型圖'''
# 建立畫板
fig=plt.figure(figsize=(20,10))
fig.suptitle('2017年各公司股價分佈',fontsize=18)
# 子圖1
ax1=plt.subplot(121)
CloseCollectDf.plot(ax=ax1,kind='box')
plt.xlabel('公司')
plt.ylabel('股價(美元)')
plt.title('2017年各公司股價分佈')
plt.grid(True,axis='y')
# 因谷歌和亞馬遜和兩外四家的差別較大,分開檢視,
# 子圖2
ax2=plt.subplot(222)
CloseCollectDf[['Google','Amazon']].plot(ax=ax2,kind='box')
# 設定x、y軸標籤及標題
plt.ylabel('股價(美元)')
plt.title('2017年穀歌和亞馬遜股價分佈')
# 設定y周標籤刻度
# plt.yticks(np.arange(0,1300,100))
# 顯示y軸網格
plt.grid(True,axis='y')
# 子圖3
ax3=plt.subplot(224)
CloseCollectDf[['Alibaba','Apple','Tencent','Facebook']].plot(ax=ax3,kind='box')
# 設定x、y軸標籤及標題
plt.xlabel('公司')
plt.ylabel('股價(美元)')
plt.title('2017年阿里、蘋果、騰訊、Facebook股價分佈')
# 設定y周標籤刻度
# plt.yticks(np.arange(0,1300,100))
# 顯示y軸網格
plt.grid(True,axis='y')
plt.subplot
# 顯示影象
plt.show()

從箱型圖看,谷歌和亞馬遜的股價分佈較廣,且中位數偏上,騰訊股價最為集中,波動最小,相對穩定。

股價走勢對比

# 建立畫板並設定大小,constrained_layout=True設定自動調整子圖之間間距
fig=plt.figure(figsize=(15,10),constrained_layout=True)
# ax=plt.subplots(2,1,sharex=True)
fig.suptitle('股價走勢對比',fontsize=18)
'''繪製影象1 '''
ax1=plt.subplot(211)
plt.plot(AliDf.index,AliDf['Close'],label='Alibaba')
plt.plot(GoogleDf.index,GoogleDf['Close'],label='Google')
plt.plot(AppleDf.index,AppleDf['Close'],label='Apple')
plt.plot(TencentDf.index,TencentDf['Close'],label='Tencent')
plt.plot(AmazonDf.index,AmazonDf['Close'],label='Amazon')
plt.plot(FacebookDf.index,FacebookDf['Close'],label='Facebook')
# # 設定xy軸標籤
plt.xlabel('時間')
plt.ylabel('股價')
# 設定標題
# plt.title('股價走勢對比')
# 圖例顯示位置、大小
plt.legend(loc='upper left',fontsize=12)
# 設定x,y軸間隔,設定旋轉角度,以免重疊
plt.xticks(AliDf.index[::10],rotation=45)
plt.yticks(np.arange(0, 1300, step=100))
# 顯示網格
plt.grid(True)
'''繪製影象2'''
ax2=plt.subplot(212)
plt.plot(AliDf.index,AliDf['sum_pct_change'],label='Alibaba')
plt.plot(GoogleDf.index,GoogleDf['sum_pct_change'],label='Google')
plt.plot(AppleDf.index,AppleDf['sum_pct_change'],label='Apple')
plt.plot(TencentDf.index,TencentDf['sum_pct_change'],label='Tencent')
plt.plot(AmazonDf.index,AmazonDf['sum_pct_change'],label='Amazon')
plt.plot(FacebookDf.index,FacebookDf['sum_pct_change'],label='Facebook')
# 設定xy軸標籤
plt.xlabel('時間')
plt.ylabel('累計增長率')
# 設定標題
# plt.title('股價走勢對比')
# 圖例顯示位置、大小
plt.legend(loc='upper left',fontsize=12)
# 設定x,y軸間隔,設定旋轉角度,以免重疊
plt.xticks(AliDf.index[::10],rotation=45)
plt.yticks(np.arange(0, 1.2, step=0.1))
# 顯示網格
plt.grid(True)
# 調整子圖間距,subplots_adjust(left=None, bottom=None, right=None, top=None,wspace=None, hspace=None)
# 顯示影象
plt.show()

可以看出,在2017年間,亞馬遜和谷歌的股價雖然偏高,漲幅卻不如阿里巴巴和騰訊。

總結

觀察以上圖形,可以得出一下結果:

1、2017年穀歌和亞馬遜股價偏高,波動較大,但其漲幅並不高;

2、2017年阿里巴巴和騰訊的股價平均值相對較小,股價波動比較小,其漲幅卻很高,分別達到了94.62%和114.36%。

本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!   


IT145.com E-mail:sddin#qq.com