要點搶先看
1.csv數(shù)據(jù)的讀取
2.利用常用函數(shù)獲取均值、中位數(shù)、方差、標(biāo)準(zhǔn)差等統(tǒng)計量
3.利用常用函數(shù)分析價格的加權(quán)均值、收益率、年化波動率等常用指標(biāo) 4.處理數(shù)據(jù)中的日期
我們最后會介紹一下NumPy庫中的一些非常實用和常用的函數(shù)方法。
要知道,NumPy的常用數(shù)學(xué)和統(tǒng)計分析的函數(shù)非常多,如果我們一個一個的分散來講,一來非常枯燥,二來呢也記不住,就仿佛又回到了昏昏欲睡的課堂,今天我們用一個背景例子來串聯(lián)一下這些零散的知識點。
我們通過分析蘋果公司的股票價格,來串講NumPy的常用函數(shù)用法
我們在我們python文件的同級目錄下放置數(shù)據(jù)文件AAPL.csv,用excel文件可以打開看看里面是什么樣的:
依次是日期,收盤價、成交量、開盤價、最高價和最低價 在CSV文件中,每一列數(shù)據(jù)數(shù)據(jù)是被“,”隔開的,為了突出重點簡化程序,我們把第一行去掉,就像下面這樣
首先,我們讀取“收盤價”和“成交量”這兩列,即第1列和第2列(csv也是從第0列開始的)
-
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.]
這樣,我們就完成了第一個任務(wù),將csv數(shù)據(jù)文件中存儲的數(shù)據(jù),讀取到我們兩個ndarray數(shù)組c和v中了。
接下來,我們小試牛刀,對收盤價進行最簡單的數(shù)據(jù)處理,求取他的平均值。
第一種,非常簡單,就是我們最常見到的算數(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)平均值,我們用成交量來加權(quán)平均價格
即,用成交量的值來作為權(quán)重,某個價格的成交量越高,該價格所占的權(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
再來說說取值范圍,找找最大值和最小值
我們找找收盤價的最大值和最小值,以及最大值和最小值之間的差異
-
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
接下來我們進行簡單的統(tǒng)計分析
我們先來求取收盤價的中位數(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
求取方差
另外一個我們關(guān)心的統(tǒng)計量就是方差,方差能夠體現(xiàn)變量變化的程度。在我們的例子中,方差還可以告訴我們投資風(fēng)險的大小。那些股價變動過于劇烈的股票一定會給持有者帶來麻煩
-
import numpy as np
-
c = np.loadtxt('AAPL.csv', delimiter=',', usecols=(1,), unpack=True)
-
print(np.var(c))
-
37.5985528621
我們回顧一下方差的定義,方差指的是各個數(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
上下對比一下,看看,結(jié)果是一模一樣的。
現(xiàn)在我們來看看每天的收益率,這個計算式子很簡單:
diff函數(shù)時用數(shù)組的第N項減第N-1項,得到一個n-1項的一維數(shù)組。本例中我們注意到數(shù)組中日期越近的收盤價,數(shù)組索引越小,因此得取一個相反數(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)差,就可以看看收益的波動大不大了:
-
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
如果我們想看看哪些天的收益率是正的,很簡單,還記得where語句嗎,拿來使用吧
-
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è)上我們對價格變動可以用一個叫做“波動率”的指標(biāo)進行度量。計算歷史波動率時需要用到對數(shù)收益率,對數(shù)收益率很簡單,就是
我們簡單的看一下下面的代碼
-
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
這里我們再強調(diào)一點就是:sqrt方法中應(yīng)用了除法計算,這里必須使用浮點數(shù)進行運算。月度波動率也是同理用1./12.即可
我們可以常常會發(fā)現(xiàn),在數(shù)據(jù)分析的過程中,對于日期的處理和分析也是一個很重要的內(nèi)容。
我們先試圖用老辦法來從csv文件中把日期數(shù)據(jù)讀出來
-
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)他報錯了,錯誤信息是不能將一個字節(jié)類型的對象轉(zhuǎn)換為浮點類型對象。原因是因為NumPy是面向浮點數(shù)運算的,那么我們對癥下藥,對日期字符串進行一些轉(zhuǎn)換處理。
我們先假定日期是一個字符串類型(下載的網(wǎng)絡(luò)數(shù)據(jù)中往往是將字符串通過utf-8編碼成字節(jié)碼,這個可以見第一季中字符編碼相關(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
通過python標(biāo)準(zhǔn)庫中的datetime函數(shù)包,我們通過指定匹配的格式%Y/%m/%d
將日期字符串轉(zhuǎn)換為了datetime類型對象,Y大寫匹配完整的四位數(shù)記年,y小寫就是兩位數(shù),例如17。
datetime對象有一個date方法,把datetime對象中的time部分去掉,變成一個純的日期,再調(diào)用weekday可以轉(zhuǎn)換為一周中的第幾天,這里是從周日開始算起的。
-
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
最后,我們回到這份蘋果公司股價的csv文件,來做一個綜合分析,來看看周幾的平均收盤價最高,周幾的最低:
-
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
簡要的再分析一下:由于從csv中讀取的數(shù)據(jù)類型為bytes,所以我們寫了一個轉(zhuǎn)換函數(shù),先將bytes類型的日期數(shù)據(jù)進行解碼(字符串編解碼詳見第一季),然后再用上一段程序介紹的方法轉(zhuǎn)換為一個表示周幾的數(shù)字
而np.loadtxt函數(shù)中的參數(shù)converters={0: datestr2num},就是說針對第一列的數(shù)據(jù),我們利用這個轉(zhuǎn)換函數(shù)將其轉(zhuǎn)化為一個數(shù)字,并將這個整形元素構(gòu)成的數(shù)組賦值給dates變量。
后面的處理就很簡單了,用循環(huán)依次取出每個工作日的收盤價構(gòu)成的數(shù)組,對其求平均值。然后得到周一到周五,五個平均值的最大值、最小值。
最后我們再介紹兩個實用函數(shù),一個是數(shù)組的裁剪函數(shù),即把比給定值還小的值設(shè)置為給定值,比給定值大的值設(shè)置為給定上限
-
import numpy as np
-
a = np.arange(5)
-
print(a.clip(1,3))
-
[11233]
第二個是一個篩選函數(shù),返回一個根據(jù)給定條件篩選后得到的結(jié)果數(shù)組
-
import numpy as np
-
a = np.arange(5)
-
print(a.compress(a >2))
-
[34]
這一小節(jié)中,我們利用NumPy的一些實用函數(shù),對蘋果公司的股價進行了一些非常非常簡單的分析,目的是通過這個實例來串講一下這些實用的數(shù)據(jù)處理函數(shù)。
其實NumPy的功能非常非常多,遠不止這些,但是沒有必要去一個一個學(xué)。并且另一方面,NumPy的方法都過于原始和底層,雖然功能很豐富,但是使用起來也很繁雜。這里我們?yōu)榇蠹掖蛞粋€基礎(chǔ),后面的章節(jié)就不會再一一介紹里面的各種函數(shù)了。后面我要介紹基于NumPy之上的一些更高層的方法庫,功能更強大,使用也更簡單。
-
蘋果
+關(guān)注
關(guān)注
61文章
24547瀏覽量
204197 -
python
+關(guān)注
關(guān)注
56文章
4828瀏覽量
87004
原文標(biāo)題:用Python分析蘋果公司股價數(shù)據(jù)
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
蘋果公司股價站上203.51美元,成人類歷史首家萬億美元公司
蘋果股價跌至半年內(nèi)最低 到底怎么了?
【轉(zhuǎn)載】蘋果公司在日本申請iWatch商標(biāo)
傳蘋果正開發(fā)下一代無線充電技術(shù)
蘋果公司的股價也在不斷波動
困獸蘋果何去何從
蘋果公司為什么要用ARM處理器
蘋果公司成為藍牙技術(shù)聯(lián)盟創(chuàng)始成員
因為iPhone8首銷不給力,蘋果股價遭遇滑鐵盧
iPhone 11銷售速度放慢 蘋果公司的股價下跌1%以上
高通起訴蘋果公司的專利被判有效率
蘋果公司正在研發(fā)的汽車預(yù)計2024年上市
A股蘋果供應(yīng)鏈公司股價大幅下挫
iPhone15發(fā)布會剛開始 蘋果公司的股價就在下跌

評論