6.NumPy的基本统计分析函数

B站影视 港台电影 2025-03-18 02:43 1

摘要:在数据分析中,对于异常值的处理可以用阈值来除去异常值,但其实有更好的方法,那就是中位数。将各个变量值按大小顺序排列起来,形成一个数列,居于数列中间位置的那个数即为中位数。在NumPy中,median的函数将帮助我们找到中位数。

在数据分析中,对于异常值的处理可以用阈值来除去异常值,但其实有更好的方法,那就是中位数。将各个变量值按大小顺序排列起来,形成一个数列,居于数列中间位置的那个数即为中位数。在NumPy中,median的函数将帮助我们找到中位数。

# 计算收盘价的中位数。import numpy as npc=np.loadtxt('data.csv', delimiter=',', usecols=(6,), unpack=True)carray([336.1 , 339.32, 345.03, 344.32, 343.44, 346.5 , 351.88, 355.2 ,358.16, 354.54, 356.85, 359.18, 359.9 , 363.13, 358.3 , 350.56,338.61, 342.62, 342.88, 348.16, 353.21, 349.31, 352.12, 359.56,360. , 355.36, 355.76, 352.47, 346.67, 351.99])m = np.median(c)m352.055# 验证sorted_close = np.sort(c, axis=0)sorted_closearray([336.1 , 338.61, 339.32, 342.62, 342.88, 343.44, 344.32, 345.03,346.5 , 346.67, 348.16, 349.31, 350.56, 351.88, 351.99, 352.12,352.47, 353.21, 354.54, 355.2 , 355.36, 355.76, 356.85, 358.16,358.3 , 359.18, 359.56, 359.9 , 360. , 363.13])n = len(c)n30sorted_close[int((n-1)/2)]351.99

这个值和median函数给出的值不一样,这是怎么回事?原因是对于长度为偶数的数组,中位数的值应该等于中间那两个数的平均值。

(sorted_close[int(n/2)] + sorted_close[int((n-1)/2)])/2352.055

方差能够体现变量变化的程度。在本例中,方差可以告诉我们投资风险的大小。那些股价变动过于剧烈的股票一定会给持有者制造麻烦。

variance = np.var(c)variance50.126517888888884

方差是指各个数据与所有数据算术平均数的离差平方和除以数据个数所得到的值。

np.mean((c - c.mean)**2)50.126517888888884

标准差(standarddeviation),又被称为标准偏差、均方差,是一种描述数据的离散程度的统计量,表示数据集合中每个数值与数据集平均值的偏离程度。标准差是方差的算术平方根。

np.std(c)7.080008325481608

收盘价的分析常常是基于简单收益率和对数收益率的。

简单收益率是指相邻两个价格之间的变化率对数收益率是指所有价格取对数后两两之间的差值,对数收益率也可以用来衡量价格的变化率

投资者最感兴趣的是收益率的方差或标准差,因为这代表着投资风险的大小。

1.简单收益率的计算

diff

NumPy中的diff函数可以返回一个由相邻数组元素的差值构成的数组。

np.diff(c)array([ 3.22, 5.71, -0.71, -0.88, 3.06, 5.38, 3.32, 2.96,-3.62, 2.31, 2.33, 0.72, 3.23, -4.83, -7.74, -11.95,4.01, 0.26, 5.28, 5.05, -3.9 , 2.81, 7.44, 0.44,-4.64, 0.4 , -3.29, -5.8 , 5.32])# 用差值除以前一天的价格。res = np.diff(c) / c[:-1]resarray([ 0.00958048, 0.01682777, -0.00205779, -0.00255576, 0.00890985,0.0155267 , 0.00943503, 0.00833333, -0.01010721, 0.00651548,0.00652935, 0.00200457, 0.00897472, -0.01330102, -0.02160201,-0.03408832, 0.01184253, 0.00075886, 0.01539897, 0.01450483,-0.01104159, 0.00804443, 0.02112916, 0.00122372, -0.01288889,0.00112562, -0.00924781, -0.0164553 , 0.01534601])# 用std函数计算标准差np.std(res)0.012922134436826306

2.对数收益率的计算

# 应检查输入数组以确保其不含有零和负数。否则,将得到一个错误提示。res = np.diff(np.log(c))resarray([ 0.00953488, 0.01668775, -0.00205991, -0.00255903, 0.00887039,0.01540739, 0.0093908 , 0.0082988 , -0.01015864, 0.00649435,0.00650813, 0.00200256, 0.00893468, -0.01339027, -0.02183875,-0.03468287, 0.01177296, 0.00075857, 0.01528161, 0.01440064,-0.011103 , 0.00801225, 0.02090904, 0.00122297, -0.01297267,0.00112499, -0.00929083, -0.01659219, 0.01522945])

我们很可能对哪些交易日的收益率为正值非常感兴趣。在完成了前面的步骤之后,我们只需要用where函数就可以做到这一点。

where函数可以根据指定的条件返回所有满足条件的数组元素的索引值。np.where(res>0)(array([ 0, 1, 4, 5, 6, 7, 9, 10, 11, 12, 16, 17, 18, 19, 21, 22, 23,25, 28], dtype=int64),)

在投资学中,波动率(volatility)是对价格变动的一种度量。历史波动率可以根据历史价格数据计算得出。计算历史波动率(如年波动率或月波动率)时,需要用到对数收益率。年波动率等于对数收益率的标准差除以其均值,再除以交易日倒数的平方根,通常交易日取252天。

# 年波动率np.std(res)/np.mean(res)/np.sqrt(1./252.)129.27478991115132# 月波动率np.std(res)/np.mean(res)/np.sqrt(1./12.)28.210071915112596

想知道股票市场是否受星期几的影响,也是值得深入研究的。

根据星期几来切分收盘价数据,并分别计算平均价格。最后,我们将找出一周中哪一天的平均收盘价最高,哪一天的最低。

# 读取日期与收盘价dates, close=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), unpack=True)ValueError Traceback (most recent call last)Cell In[90], line 21 # 读取日期与收盘价----> 2 dates, close=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), unpack=True)File D:\anaconda3\Lib\site-packages\numpy\lib\npyio.py:1373, in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows, quotechar, like)1370 if isinstance(delimiter, bytes):1371 delimiter = delimiter.decode('latin1')-> 1373 arr = _read(fname, dtype=dtype, comment=comment, delimiter=delimiter,1374 converters=converters, skiplines=skiprows, usecols=usecols,1375 unpack=unpack, ndmin=ndmin, encoding=encoding,1376 max_rows=max_rows, quote=quotechar)1378 return arrfile D:\anaconda3\Lib\site-packages\numpy\lib\npyio.py:1016, in _read(fname, delimiter, comment, quote, imaginary_unit, usecols, skiplines, max_rows, converters, ndmin, unpack, dtype, encoding)1013 data = _preprocess_comments(data, comments, encoding)1015 if read_dtype_via_object_chunks is None:-> 1016 arr = _load_from_filelike(1017 data, delimiter=delimiter, comment=comment, quote=quote,1018 imaginary_unit=imaginary_unit,1019 usecols=usecols, skiplines=skiplines, max_rows=max_rows,1020 converters=converters, dtype=dtype,1021 encoding=encoding, filelike=filelike,1022 byte_converters=byte_converters)1024 else:1025 # This branch reads the file into chunks of object arrays and then1026 # casts them to the desired actual dtype. This ensures correct1027 # string-length and datetime-unit discovery (like `arr.astype`).1028 # Due to chunking, certain error reports are less clear, currently.1029 if filelike:ValueError: could not convert string '28-01-2011' to float64 at row 0, column 2.

NumPy是面向浮点数运算的,因此需要对日期做一些专门的处理。

在loadtxt函数中使用converters参数,它是数据列和转换函数之间进行映射的字典。如:

import datetimedef datestr2num(s): return datetime.datetime.strptime(s.decode, "%d-%m-%Y").date.weekday

这里返回值为数字,可以是0到6的整数,0代表星期一,6代表星期天。

dates, close=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), converters={1:datestr2num}, unpack=True)datesarray([4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4., 1.,2., 3., 4., 0., 1., 2., 3., 4., 0., 1., 2., 3., 4.])

如你所见,没有出现星期六和星期天。股票交易在周末是休市的。

# 根据星期几来切分收盘价数据,并分别计算平均价格。averages = np.zeros(5)for i in range(5):index = np.where(dates == i)price = np.take(close, index)averages[i] = np.mean(price)print('Day {0} price {1}, average: {2}'.format(i, price, averages[i]))Day 0 price [[339.32 351.88 359.18 353.21 355.36]], average: 351.7900000000001Day 1 price [[345.03 355.2 359.9 338.61 349.31 355.76]], average: 350.63500000000005Day 2 price [[344.32 358.16 363.13 342.62 352.12 352.47]], average: 352.1366666666666Day 3 price [[343.44 354.54 358.3 342.88 359.56 346.67]], average: 350.8983333333333Day 4 price [[336.1 346.5 356.85 350.56 348.16 360. 351.99]], average: 350.0228571428571averagesarray([351.79 , 350.635 , 352.13666667, 350.89833333,350.02285714])where函数会根据指定的条件返回所有满足条件的数组元素的索引值。take函数可以按照这些索引值从数组中取出相应的元素。# 找出平均收盘价中的最高值和最低值,以及其索引np.max(averages)352.1366666666666np.argmax(averages)2np.min(averages)350.0228571428571np.argmin(averages)4

argmin函数返回的是averages数组中最小元素的索引值,这里是4,也就是星期五。 argmax函数返回的是averages数组中最大元素的索引值,这里是2,也就是星期三。

在本例中,这些数据是将一整天的交易数据汇总得到的。如果有数十年的数据,可能希望对数据做进一步的汇总和压缩。接下来,我们来把苹果股票数据按周进行汇总。

周汇总的目的是汇总每周的开票价、最高价、最低价及收盘价。

由于要汇总整个交易周中从周一到周五的所有数据。数据覆盖的时间段内有一个节假日:2月21日是总统纪念日。这天是星期一,美国股市休市,因此在我们的示例数据中没有这一天的数据记录。为了简单起见,我们只考虑前三周的数据,这样就避免了节假日造成的数据缺失。

# 读取数据dates, open, high, low, close=np.loadtxt('data.csv', delimiter=',', usecols=(1, 3, 4, 5, 6), converters={1: datestr2num}, unpack=True)close = close[:16] dates = dates[:16]# 找到示例数据中第一个星期一的索引first_monday = np.ravel(np.where(dates==0))[0]first_monday1# 找到示例数据中最后一个星期五的索引last_friday = np.ravel(np.where(dates==4))[-1]last_friday15# 创建一个数组,用于存储三周内每天的索引值week_index = np.arange(first_monday, last_friday + 1)# 用split函数切分数组,切分成3个子数组week_index = np.split(week_index, 3)week_index[array([1, 2, 3, 4, 5], dtype=int64),array([ 6, 7, 8, 9, 10], dtype=int64),array([11, 12, 13, 14, 15], dtype=int64)]# week_index 是一个二维数组np.ndim(week_index)2

在NumPy中,数组的维度也被称作轴。现在我们来熟悉一下apply_along_axis函数。 这个函数会调用另外一个由我们给出的函数,作用于每一个数组元素上。目前我们的数组中有3个元素,分别对应于示例数据中的3个星期,元素中的索引值对应于示例数据中的1天。在调用apply_along_axis时提供我们自定义的函数名summarize,并指定要作用的轴或维度的编号(如取1),目标数组以及可变数量的summarize函数的参数。

# w - week index,o - open,h - high,l - low,c - closedef summarize(w, o, h, l, c):monday_open = o[w[0]]week_high = np.max(np.take(h, w))week_low = np.min(np.take(l, w))friday_close = c[w[-1]]return ('APPL', monday_open, week_high, week_low, friday_close)weeksummary = np.apply_along_axis(summarize, 1, week_index, open, high, low, close)weeksummaryarray([['APPL', '335.8', '346.7', '334.3', '346.5'],['APPL', '347.89', '360.0', '347.64', '356.85'],['APPL', '356.79', '364.9', '349.52', '350.56']], dtype='# 使用NumPy中的savetxt函数,将数据保存至文件。np.savetxt("weeksummary.csv", weeksummary, delimiter=",", fmt="%s")

来源:IT职业教育

相关推荐