要點(diǎn)搶先看
1.csv數(shù)據(jù)的讀取
2.利用常用函數(shù)獲取均值、中位數(shù)、方差、標(biāo)準(zhǔn)差等統(tǒng)計(jì)量
3.利用常用函數(shù)分析價(jià)格的加權(quán)均值、收益率、年化波動(dòng)率等常用指標(biāo) 4.處理數(shù)據(jù)中的日期
我們最后會(huì)介紹一下NumPy庫(kù)中的一些非常實(shí)用和常用的函數(shù)方法。
要知道,NumPy的常用數(shù)學(xué)和統(tǒng)計(jì)分析的函數(shù)非常多,如果我們一個(gè)一個(gè)的分散來(lái)講,一來(lái)非常枯燥,二來(lái)呢也記不住,就仿佛又回到了昏昏欲睡的課堂,今天我們用一個(gè)背景例子來(lái)串聯(lián)一下這些零散的知識(shí)點(diǎn)。
我們通過(guò)分析蘋(píng)果公司的股票價(jià)格,來(lái)串講NumPy的常用函數(shù)用法
我們?cè)谖覀?a href="http://www.1cnz.cn/tags/python/" target="_blank">python文件的同級(jí)目錄下放置數(shù)據(jù)文件AAPL.csv,用excel文件可以打開(kāi)看看里面是什么樣的:
依次是日期,收盤(pán)價(jià)、成交量、開(kāi)盤(pán)價(jià)、最高價(jià)和最低價(jià) 在CSV文件中,每一列數(shù)據(jù)數(shù)據(jù)是被“,”隔開(kāi)的,為了突出重點(diǎn)簡(jiǎn)化程序,我們把第一行去掉,就像下面這樣
首先,我們讀取“收盤(pán)價(jià)”和“成交量”這兩列,即第1列和第2列(csv也是從第0列開(kāi)始的)
-
import numpy as np
-
c, v = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,2), unpack=True)
-
print(c)
-
print(v)
-
[178.02178.65178.44179.97181.72179.98176.94175.03176.67 176.82176.21175. 178.12178.39178.97175.5 172.5 171.07 171.85172.43172.99167.37164.34162.71156.41155.15159.54 163.03156.49160.5 167.78167.43166.97167.96171.51171.11 174.22177.04177. 178.46179.26179.1 176.19177.09175.28 174.29174.33174.35175. 173.03172.23172.26169.23171.08 170.6 170.57175.01175.01174.35174.54176.42]
-
[38313330.22676520.29334630.31464170.32191070.32130360. 24518850.31686450.23273160.27825140.38426060.48706170. 37568080.38885510.37353670.33772050.30953760.37378070. 33690660.40113790.50908540.40382890.32483310.60774900. 70583530.54145930.51467440.68171940.72215320.85957050. 44453230.32234520.45635470.50565420.39075250.41438280. 51368540.32395870.27052000.31306390.31087330.34260230. 29512410.25302200.18653380.23751690.21532200.20523870. 23589930.22342650.29461040.25400540.25938760.16412270. 21477380.33113340.16339690.20848660.23451420.27393660. 29385650.]
這樣,我們就完成了第一個(gè)任務(wù),將csv數(shù)據(jù)文件中存儲(chǔ)的數(shù)據(jù),讀取到我們兩個(gè)ndarray數(shù)組c和v中了。
接下來(lái),我們小試牛刀,對(duì)收盤(pán)價(jià)進(jìn)行最簡(jiǎn)單的數(shù)據(jù)處理,求取他的平均值。
第一種,非常簡(jiǎn)單,就是我們最常見(jiàn)到的算數(shù)平均值
-
import numpy as np
-
c, v = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,2), unpack=True)
-
mean_c = np.mean(c)print(mean_c)
-
172.614918033
第二種,是加權(quán)平均值,我們用成交量來(lái)加權(quán)平均價(jià)格
即,用成交量的值來(lái)作為權(quán)重,某個(gè)價(jià)格的成交量越高,該價(jià)格所占的權(quán)重就越大。
-
import numpy as np
-
c, v = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,2), unpack=True)
-
vwap = np.average(c, weights=v)
-
print(vwap)
-
170.950010035
再來(lái)說(shuō)說(shuō)取值范圍,找找最大值和最小值
我們找找收盤(pán)價(jià)的最大值和最小值,以及最大值和最小值之間的差異
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
print(np.max(c))
-
print(np.min(c))
-
print(np.ptp(c))
-
181.72
-
155.15
-
26.57
接下來(lái)我們進(jìn)行簡(jiǎn)單的統(tǒng)計(jì)分析
我們先來(lái)求取收盤(pán)價(jià)的中位數(shù)
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
print(np.max(c))
-
print(np.min(c))
-
print(np.median(c))
-
181.72
-
155.15
-
174.35
求取方差
另外一個(gè)我們關(guān)心的統(tǒng)計(jì)量就是方差,方差能夠體現(xiàn)變量變化的程度。在我們的例子中,方差還可以告訴我們投資風(fēng)險(xiǎn)的大小。那些股價(jià)變動(dòng)過(guò)于劇烈的股票一定會(huì)給持有者帶來(lái)麻煩
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
print(np.var(c))
-
37.5985528621
我們回顧一下方差的定義,方差指的是各個(gè)數(shù)據(jù)與所有數(shù)據(jù)算數(shù)平均數(shù)的離差平方和的均值
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
print(np.mean((c - c.mean())**2))
-
37.5985528621
上下對(duì)比一下,看看,結(jié)果是一模一樣的。
現(xiàn)在我們來(lái)看看每天的收益率,這個(gè)計(jì)算式子很簡(jiǎn)單:
diff函數(shù)時(shí)用數(shù)組的第N項(xiàng)減第N-1項(xiàng),得到一個(gè)n-1項(xiàng)的一維數(shù)組。本例中我們注意到數(shù)組中日期越近的收盤(pán)價(jià),數(shù)組索引越小,因此得取一個(gè)相反數(shù),綜上代碼:
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
returns =-np.diff(c)/c[1:]
-
print(returns)
-
[-0.003526450.00117687-0.00850142-0.0096302 0.009667740.01718097 0.01091242-0.00928284-0.000848320.003461780.00691429-0.01751628-0.00151354-0.003240770.019772080.0173913 0.00835915-0.00453884-0.00336368-0.003237180.0335783 0.018437390.010017820.04027875 0.00812117-0.02751661-0.0214071 0.04179181-0.02498442-0.04339015 0.002090430.00275499-0.00589426-0.0206985 0.00233768-0.01785099-0.0159286 0.00022599-0.00818111-0.004462790.000893360.01651626-0.005082160.010326340.00568019-0.00022945-0.00011471-0.00371429 0.011385310.00464495-0.000174160.01790463-0.010813650.0028136 0.00017588-0.02536998-0. 0.00378549-0.00108858-0.01065639]
然后觀察一下每日收益的標(biāo)準(zhǔn)差,就可以看看收益的波動(dòng)大不大了:
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
returns =-np.diff(c)/c[1:]
-
print(np.std(returns))
-
0.0150780328454
如果我們想看看哪些天的收益率是正的,很簡(jiǎn)單,還記得where語(yǔ)句嗎,拿來(lái)使用吧
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
returns =-np.diff(c)/c[1:]
-
print(np.where(returns>0))
-
(array([1,4,5,6,9,10,14,15,16,20,21,22,23,24,27,30,31,34,37,40,41,43,44,48,49,51,53,54,57], dtype=int64),)
專業(yè)上我們對(duì)價(jià)格變動(dòng)可以用一個(gè)叫做“波動(dòng)率”的指標(biāo)進(jìn)行度量。計(jì)算歷史波動(dòng)率時(shí)需要用到對(duì)數(shù)收益率,對(duì)數(shù)收益率很簡(jiǎn)單,就是
我們簡(jiǎn)單的看一下下面的代碼
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
logreturns =-np.diff(np.log(c))
-
volatility = np.std(logreturns)/ np.mean(logreturns)
-
annual_volatility = volatility / np.sqrt(1./252.)
-
print(volatility)
-
print(annual_volatility)
-
100.096757388
-
1588.98676256
這里我們?cè)購(gòu)?qiáng)調(diào)一點(diǎn)就是:sqrt方法中應(yīng)用了除法計(jì)算,這里必須使用浮點(diǎn)數(shù)進(jìn)行運(yùn)算。月度波動(dòng)率也是同理用1./12.即可
我們可以常常會(huì)發(fā)現(xiàn),在數(shù)據(jù)分析的過(guò)程中,對(duì)于日期的處理和分析也是一個(gè)很重要的內(nèi)容。
我們先試圖用老辦法來(lái)從csv文件中把日期數(shù)據(jù)讀出來(lái)
-
import numpy as np
-
dates,c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(0,1), unpack=True)
-
Traceback(most recent call last):
-
File"E:/12homework/12homework.py", line 2,in
-
dates,c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(0,1), unpack=True)
-
File"C:\Python34\lib\site-packages\numpy\lib\npyio.py", line 930,in loadtxt
-
items =[conv(val)for(conv, val)in zip(converters, vals)]
-
File"C:\Python34\lib\site-packages\numpy\lib\npyio.py", line 930,in
-
items =[conv(val)for(conv, val)in zip(converters, vals)]
-
File"C:\Python34\lib\site-packages\numpy\lib\npyio.py", line 659,in floatconv
-
returnfloat(x)
-
ValueError: could not convert string to float: b'2018/3/16'
我們發(fā)現(xiàn)他報(bào)錯(cuò)了,錯(cuò)誤信息是不能將一個(gè)字節(jié)類型的對(duì)象轉(zhuǎn)換為浮點(diǎn)類型對(duì)象。原因是因?yàn)镹umPy是面向浮點(diǎn)數(shù)運(yùn)算的,那么我們對(duì)癥下藥,對(duì)日期字符串進(jìn)行一些轉(zhuǎn)換處理。
我們先假定日期是一個(gè)字符串類型(下載的網(wǎng)絡(luò)數(shù)據(jù)中往往是將字符串通過(guò)utf-8編碼成字節(jié)碼,這個(gè)可以見(jiàn)第一季中字符編碼相關(guān)內(nèi)容的介紹)
-
import numpy as np import datetime
-
strdate ='2017/3/16'
-
d = datetime.datetime.strptime(strdate,'%Y/%m/%d')
-
print(type(d))
-
print(d)
-
<class'datetime.datetime'>
-
2017-03-1600:00:00
通過(guò)python標(biāo)準(zhǔn)庫(kù)中的datetime函數(shù)包,我們通過(guò)指定匹配的格式%Y/%m/%d
將日期字符串轉(zhuǎn)換為了datetime類型對(duì)象,Y大寫(xiě)匹配完整的四位數(shù)記年,y小寫(xiě)就是兩位數(shù),例如17。
datetime對(duì)象有一個(gè)date方法,把datetime對(duì)象中的time部分去掉,變成一個(gè)純的日期,再調(diào)用weekday可以轉(zhuǎn)換為一周中的第幾天,這里是從周日開(kāi)始算起的。
-
import numpy as np import datetime
-
strdate ='2018/3/16'
-
d = datetime.datetime.strptime(strdate,'%Y/%m/%d')
-
print(d.date())
-
print(d.date().weekday())
-
2018-03-164
最后,我們回到這份蘋(píng)果公司股價(jià)的csv文件,來(lái)做一個(gè)綜合分析,來(lái)看看周幾的平均收盤(pán)價(jià)最高,周幾的最低:
-
import numpy as np import datetime
-
def datestr2num(bytedate):
-
return datetime.datetime.strptime(
-
bytedate.decode('utf-8'),'%Y/%m/%d').date().weekday()
-
dates,c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(0,1),
-
converters={0: datestr2num}, unpack=True)
-
averages = np.zeros(5)
-
for i in range(5):
-
index = np.where(dates == i)
-
prices = np.take(c, index)
-
avg = np.mean(prices)
-
averages[i]= avg print("Day {} prices: {},avg={}".format(i,prices,avg))
-
top = np.max(averages)
-
top_index = np.argmax(averages)
-
bot = np.min(averages)
-
bot_index = np.argmin(averages)
-
print('highest:{}, top day is {}'.format(top,top_index))
-
print('lowest:{},bottom day is {}'.format(bot,bot_index))
-
Day0 prices:[[181.72176.82178.97162.71156.49167.96177. 174.35176.42]],avg=172.49333333333334
-
Day1 prices:[[179.97176.67178.39171.85164.34163.03166.97177.04176.19 174.33172.26170.57174.54]],avg=172.78076923076924
-
Day2 prices:[[178.44175.03178.12171.07167.37159.54167.43174.22179.1 174.29172.23170.6 174.35]],avg=172.44538461538463
-
Day3 prices:[[178.65176.94175. 172.5 172.99155.15167.78171.11179.26 175.28173.03171.08175.01]],avg=172.59846153846152
-
Day4 prices:[[178.02179.98176.21175.5 172.43156.41160.5 171.51178.46 177.09175. 169.23175.01]],avg=172.71923076923073
-
highest:172.78076923076924, top day is1
-
lowest:172.44538461538463,bottom day is2
簡(jiǎn)要的再分析一下:由于從csv中讀取的數(shù)據(jù)類型為bytes,所以我們寫(xiě)了一個(gè)轉(zhuǎn)換函數(shù),先將bytes類型的日期數(shù)據(jù)進(jìn)行解碼(字符串編解碼詳見(jiàn)第一季),然后再用上一段程序介紹的方法轉(zhuǎn)換為一個(gè)表示周幾的數(shù)字
而np.loadtxt函數(shù)中的參數(shù)converters={0: datestr2num},就是說(shuō)針對(duì)第一列的數(shù)據(jù),我們利用這個(gè)轉(zhuǎn)換函數(shù)將其轉(zhuǎn)化為一個(gè)數(shù)字,并將這個(gè)整形元素構(gòu)成的數(shù)組賦值給dates變量。
后面的處理就很簡(jiǎn)單了,用循環(huán)依次取出每個(gè)工作日的收盤(pán)價(jià)構(gòu)成的數(shù)組,對(duì)其求平均值。然后得到周一到周五,五個(gè)平均值的最大值、最小值。
最后我們?cè)俳榻B兩個(gè)實(shí)用函數(shù),一個(gè)是數(shù)組的裁剪函數(shù),即把比給定值還小的值設(shè)置為給定值,比給定值大的值設(shè)置為給定上限
-
import numpy as np
-
a = np.arange(5)
-
print(a.clip(1,3))
-
[11233]
第二個(gè)是一個(gè)篩選函數(shù),返回一個(gè)根據(jù)給定條件篩選后得到的結(jié)果數(shù)組
-
import numpy as np
-
a = np.arange(5)
-
print(a.compress(a >2))
-
[34]
這一小節(jié)中,我們利用NumPy的一些實(shí)用函數(shù),對(duì)蘋(píng)果公司的股價(jià)進(jìn)行了一些非常非常簡(jiǎn)單的分析,目的是通過(guò)這個(gè)實(shí)例來(lái)串講一下這些實(shí)用的數(shù)據(jù)處理函數(shù)。
其實(shí)NumPy的功能非常非常多,遠(yuǎn)不止這些,但是沒(méi)有必要去一個(gè)一個(gè)學(xué)。并且另一方面,NumPy的方法都過(guò)于原始和底層,雖然功能很豐富,但是使用起來(lái)也很繁雜。這里我們?yōu)榇蠹掖蛞粋€(gè)基礎(chǔ),后面的章節(jié)就不會(huì)再一一介紹里面的各種函數(shù)了。后面我要介紹基于NumPy之上的一些更高層的方法庫(kù),功能更強(qiáng)大,使用也更簡(jiǎn)單。
-
蘋(píng)果
+關(guān)注
關(guān)注
61文章
24398瀏覽量
198586 -
python
+關(guān)注
關(guān)注
56文章
4793瀏覽量
84634
原文標(biāo)題:用Python分析蘋(píng)果公司股價(jià)數(shù)據(jù)
文章出處:【微信號(hào):magedu-Linux,微信公眾號(hào):馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論