Python学习之数据分析库一(Numpy入门)

目录

一、关于Numpy

1.什么是Numpy?

2.Numpy的优势

二、Numpy安装

三、Numpy的简单应用

1.Numpy创建数组

2.矩阵的转置

3.Numpy的索引和片

4.Numpy中数值的修改

5.获取矩阵的四角元素

6、数组形状的修改

7、数组拼接

8、数组分割

9、数组元素的添加和删除

10、numpy的统计函数

二、案例一(Numpy学生身高体重统计分析)

三、案例二(基于Numpy的股价统计分析和应用)


一、关于Numpy

1.什么是Numpy?

NumPy(Numerical Python)是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix)),支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。

NumPy(Numeric Python)提供了许多高级的数值编程工具,如:矩阵数据类型、矢量处理,以及精密的运算库。专为进行严格的数字处理而产生。多为很多大型金融公司使用,以及核心的科学计算组织如:Lawrence Livermore,NASA用其处理一些本来使用C++,Fortran或Matlab等所做的任务。

总之,NumPy 是一个运行速度非常快的数学库,主要用于数组计算,主要包含:

  • 一个强大的N维数组对象 ndarray
  • 广播功能函数
  • 整合 C/C++/Fortran 代码的工具
  • 线性代数、傅里叶变换、随机数生成等功能

2.Numpy的优势

  • numpy内置了并行运算功能,当系统有多个核心时,做某种计算时,numpy会自动做并行计算。
  • Numpy底层使用C语言编写,数组中直接存储对象,而不是存储对象指针,所以其运算效率远高于纯Python代码。

了解更多关于Numpy的 内容,请点击这里:点我点我

二、Numpy安装

1. 普通安装:pip install numpy

2.使用豆瓣源快速安装:pip install -i https://pypi.douban.com/simple numpy

三、Numpy的简单应用

1.Numpy创建数组

# 导入numppy库, 对numpy重命名为np。
import numpy as np

# 1). 创建数组: a, b, c创建的数组相同, 任选一种;
# 方法一: 直接将数组/列表传入array方法中, 将数据类型转换为ndarray.
a = np.array([1, 2, 3, 4, 5])
# array方法传入的值可以是range对象
# 方法二: 将range对象传入array方法中, dtype:数据类型dtype=np.float 将元素转换为float
b = np.array(range(1, 6))
print(b)
li = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11.8, 12]
]
# 转换数据类型时可以通过dtype对数组的所有对象转换类型. eg: dtype=np.int将元素转成int
li_ndarray = np.array(li, dtype=np.int)
print(li_ndarray)

# 方法三: 直接生成指定的数值
c = np.arange(1, 6)
# arange和range的基本语法和参数一致。 arange的优点: 可以生成小数区间.
d = np.arange(2.2, 13.3, 0.2)
print(a, b, c)

# # # 2). 查看numpy创建的数组类型
print(type(a))
print(type(b))
print(type(c))

# 3). 查看数组存储的数据类型, 常见的数据类型还有哪些?
print(a.dtype)   # 为什么是int64? 因为硬件架构是64位;

# # 4). 制定创建的数组的数据类型
d = np.array([1.9, 0, 1.3, 0], dtype=np.float)
print(d, d.dtype)

# 5). 修改数组的数据类型
e = d.astype('int64')   # 里面可以是数据类型, 也可以是数据代码;int64---i1
print(e, e.dtype)

# 6). 修改浮点数的小数点位数
# 随机创建一个三行四列的数组;
f = np.random.random((3, 4))
print(f)

# 修改浮点值的小数位数为3位
g = np.round(f, 3)
print(g)

运行结果

 

2.矩阵的转置

实现转置有三种方法,代码如下:

import numpy as np

# 生成一个0~1之间的数值,3*4维的矩阵
data = np.random.random(size=(3,4))
print(data)

# 转换成2*6的矩阵
data = data.reshape((2,6))
print(data)

# 转置
print(data.shape)
# 方法1
print("转置:", data.T)
# 方法2
print("转置:", data.transpose())
# numpy里面轴分为0轴(x行)和1轴(y行),这里将y轴和x轴互换实现转置
# 方法3
print("转置:", data.swapaxes(1,0))

 运行结果:

3.Numpy的索引和片

注意:只有一个参数时,默认获取的是行,有两个参数时,第一个参数代表行,第二个参数代表列。行和列的索引是从0开始的。

import numpy as np
#1)生成测试数据
a = np.arange(12).reshape((3, 4))
print(a)

# *****************取单行或者单列*********************
# 取第2行;
print(a[1])
# 取第3列;
print(a[:, 2])
# 获取第2行3列的数据
print(a[1, 2])

# *****************取连续行或者列*********************
# 取第2行和第3行;
print(a[1:3])

# 取第3列和第4列
print(a[:, 2:4])

# 行: 1和2   列: 2
print(a[0:2, 1:2])

# *****************取不连续的行或者列*********************
# 行: 1和3   列: all 获取第一行和第三行的所有元素
print(a[[0, 2], :])
# 行: all   列: 1, 4
print(a[:, [0, 3]])
# 行: 1 , 3   列: 1 4  获取第一行第一列的元素, 和第三行第4列的元素
print("*"*10)
print(a[[0, 2], [0, 3]])

运行结果:

 

4.Numpy中数值的修改

Numpy中数值的修改有三种方法:

  • 根据索引/切片对元素进行赋值;
  • 根据布尔索引,满足条件Bool=True,则赋值,否则不做任何修改;
  • numpy的三元运算符t<100?0:10,t<100,则赋值0,否则赋值10。

import numpy as np

# 执行行和指定列的修改
t = np.arange(24).reshape((4, 6))
print(t)

# 方法一: 根据索引/切片对元素进行赋值。
#行: all, 列: 3,4
# 索引的思路: 2~4-1  列: 3~4
# 行/列的位置: 3~4
t[:, 2:4] = 0
print(t)

# 方法二: 布尔索引, 满足条件/Bool=True,则赋值, 否则, 不做修改
# 返回的是矩阵(和t的size一样), 存储的是Bool类型
print(t < 10)

t[t < 10] = 100
print(t)

t[t > 20] = 200
print(t)


# 方法三: numpy的三元运算符 t<100?0:10
# 满足条件/Bool=True,则赋值=value1, 否则,赋值=value2
t1  = np.where(t < 100, 0, 10)
print(t)
print(t1)

 3.运行结果:

5.获取矩阵的四角元素

如下两个例子:

"""
获取了 4X3 数组中的四个角的元素。 行索引是 [0,0] 和 [3,3],而列索引是 [0,2] 和 [0,2]。
1 2 3 4
5 6 7 8
9 10 11
"""
import numpy as np
def get_edge(data):
    """获取了数组中的四个角的元素"""
    row, column = data.shape
    rows = np.array([[0, 0], [row - 1, row - 1]])
    cols = np.array([[0, column - 1], [0, column - 1]])
    return  data[rows, cols]

if __name__ == '__main__':
    x = np.arange(30).reshape((5, 6))
    print("data:", x)
    print("result: ", get_edge(x))

运行结果:

 

import numpy as np
row, column = x.shape  # row=4 column=3
# rows = np.array([[0, 0], [3, 3]])   # 获取的行信息
# cols = np.array([[0, 2], [0, 2]])   # 获取的列信息

rows = np.array([[0, 0], [row-1, row-1]])
cols = np.array([[0, column-1], [0, column-1]])
y = x[rows, cols]
print('这个数组的四个角元素是:')
print(y)

测试结果:

 

6、数组形状的修改

reshape 不改变数据的条件下修改形状
    unmpy.reshape(arr, newshape, order='C')
    order='C'---按行, 'F'---按列, 'A'---原序列, 'K'---元素在内存中出现的顺序
flat   数组元素迭代器
flatten  返回一份数组拷贝,对拷贝所作的修改不会影响原始数据
ravel 返回展开数组
"""
    reshape	不改变数据的条件下修改形状
         numpy.reshape(arr, newshape, order='C')
         order:'C' -- 按行,'F' -- 按列,'A' -- 原顺序,'k' -- 元素在内存中的出现顺序。
    flat	数组元素迭代器

    flatten	返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
    ravel	返回展开数组
"""

import numpy as np

print("****************************************flat********************************")
a = np.arange(9).reshape(3, 3)
print('原始数组:')
for row in a:
    print(row)

# # 对数组中每个元素都进行处理(展开),可以使用flat属性,该属性是一个数组元素迭代器:
print('迭代后的数组:')
for element in a.flat:
    print(element)

#
print("*********************************flatten**************************************")
a = np.arange(8).reshape(2, 4)

print('原数组:')
print(a)
print('\n')
# 默认按行

print('展开的数组:')
print(a.flatten())
print('\n')

print('以 F 风格顺序展开的数组:')
print(a.flatten(order='F'))


print("*********************************ravel*************************************")
a = np.arange(8).reshape(2, 4)

print('原数组:')
print(a)
print('\n')
#
print('调用 ravel 函数之后:')
print(a.ravel())
print('\n')

print('以 F 风格顺序调用 ravel 函数之后:')
print(a.ravel(order='F'))

运行结果:

****************************************flat********************************
原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8
*********************************flatten**************************************
原数组:
[[0 1 2 3]
 [4 5 6 7]]


展开的数组:
[0 1 2 3 4 5 6 7]


以 F 风格顺序展开的数组:
[0 4 1 5 2 6 3 7]
*********************************ravel*************************************
原数组:
[[0 1 2 3]
 [4 5 6 7]]


调用 ravel 函数之后:
[0 1 2 3 4 5 6 7]


以 F 风格顺序调用 ravel 函数之后:
[0 4 1 5 2 6 3 7]

Process finished with exit code 0

 

7、数组拼接

concatenate 连接沿现有轴的数组序列
stack  沿着新的轴加入一系列数组。
hstack 水平堆叠序列中的数组(列方向)
vstack 竖直堆叠序列中的数组(行方向)
import numpy as np
print("******************** concatenate ****************")
a = np.array([[1, 2], [3, 4]])
print('第一个数组:')
print(a)
print('\n')

b = np.array([[5, 6], [7, 8]])
print('第二个数组:')
print(b)
print('\n')

# 两个数组的维度相同
# x轴和y轴, 1轴和0轴
print('沿轴 0 连接两个数组:')
print(np.concatenate((a, b)))
print('\n')

print('沿轴 1 连接两个数组:')
print(np.concatenate((a, b), axis=1))

print("*************************stack*********************************")
a = np.array([[1, 2], [3, 4]])

print('第一个数组:')
print(a)
print('\n')
b = np.array([[5, 6], [7, 8]])

print('第二个数组:')
print(b)
print('\n')

print('沿轴 0 堆叠两个数组:')
print(np.stack((a, b), axis=0))
print('\n')

print('沿轴 1 堆叠两个数组:')
print(np.stack((a, b), axis=1))

print("**************************************hstack + vstack*************************************")
a = np.array([[1, 2], [3, 4]])

print('第一个数组:')
print(a)
print('\n')
b = np.array([[5, 6], [7, 8]])

print('第二个数组:')
print(b)
print('\n')

print('水平堆叠:')
c = np.hstack((a, b))
print(c)
print('\n')

print('竖直堆叠:')
c = np.vstack((a, b))
print(c)
print('\n')

运行结果:

******************** concatenate ****************
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


沿轴 0 连接两个数组:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]


沿轴 1 连接两个数组:
[[1 2 5 6]
 [3 4 7 8]]
*************************stack*********************************
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


沿轴 0 堆叠两个数组:
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]


沿轴 1 堆叠两个数组:
[[[1 2]
  [5 6]]

 [[3 4]
  [7 8]]]
**************************************hstack + vstack*************************************
第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


水平堆叠:
[[1 2 5 6]
 [3 4 7 8]]


竖直堆叠:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

 

8、数组分割

split   将一个数组分割为多个子数组
    numpy.split(ary, indices_or_sections, axis)
hsplit 将一个数组水平分割为多个子数组(按列)
vsplit     将一个数组垂直分割为多个子数组(按行)
import numpy as np
print("**********************split******************************")
a = np.arange(9)
print('第一个数组:')
print(a)
print('\n')

print('将数组分为三个大小相等的子数组:')
b = np.split(a, 3)
print(b)
print('\n')

print('将数组在一维数组中表明的位置分割:')
b = np.split(a, [1, 7])
print(b)

print('******************hsplit*****************')
harr = np.arange(12).reshape((3, 4))
print('原array:')
print(harr)

print('横向拆分后:')
print(np.hsplit(harr, 2))

print("***************************vsplit****************************")
a = np.arange(12).reshape(4, 3)
print('第一个数组:')
print(a)
print('\n')

print('竖直分割:')
b = np.vsplit(a, 2)
print(b)

  运行结果:

**********************split******************************
第一个数组:
[0 1 2 3 4 5 6 7 8]


将数组分为三个大小相等的子数组:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]


将数组在一维数组中表明的位置分割:
[array([0]), array([1, 2, 3, 4, 5, 6]), array([7, 8])]
******************hsplit*****************
原array:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
横向拆分后:
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11]])]
***************************vsplit****************************
第一个数组:
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]


竖直分割:
[array([[0, 1, 2],
       [3, 4, 5]]), array([[ 6,  7,  8],
       [ 9, 10, 11]])]

9、数组元素的添加和删除

resize  返回指定形状的新数组
append  将值添加到数组末尾
insert  沿指定轴将值插入指定下标之前
delete  删除某个轴的子数组,并返回删除后的新数组
unique  查找数组中的唯一元素
    arr:输入数组,如果不是一维数组则会展开
    return_index:如果为true,则返回新列表元素在旧列表元素中的位置(下标),并以列表形式存储
    return_counts:如果为true,返回去重数组中的元素在原数组中出现的次数

 


import numpy as np

print('***************append****************')
a = np.array([[1, 2, 3], [4, 5, 6]])

print('第一个数组:')
print(a)
print('\n')

print('向数组添加元素:')
# 没有指定行/列追加元素时, 默认先把前面的元素展开,再追加
print(np.append(a, [7, 8, 9]))      # [1 2 3 4 5 6 7 8 9]
print('\n')

print('沿轴 0 添加元素:')
print(np.append(a, [[7, 8, 9]], axis=0))
print('\n')

print('沿轴 1 添加元素:')
print(np.append(a, [[5, 5, 5], [7, 8, 9]], axis=1))

print('******************************insert****************************************')
a = np.array([[1, 2], [3, 4], [5, 6]])

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.insert(a, 3, [11, 12]))
print('\n')

print('传递了 Axis 参数。 会广播值数组来配输入数组。')
print('沿轴 0 广播:')
print(np.insert(a, 1, [11, 100], axis=0))
print('\n')

print('沿轴 1 广播:')
print(np.insert(a, 1, [11,12, 13], axis=1))

print('***********************delete******************************************')
a = np.arange(12).reshape(3, 4)

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.delete(a, 5))
print('\n')

print('删除第二列:')
print(np.delete(a, 1, axis=1))
print('\n')

print('删除第二行:')
print(np.delete(a, 1, axis=0))
print('\n')

print('包含从数组中删除的替代值的切片:')
a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
"""
np.s_ 为阵列建立索引元组的一种更好的方法。 返回的时slice对象;
也可以使用`Slice()‘加上一些特殊的对象来完成所有这些操作但这个版本更简单,因为它使用了标准的数组索引语法。
"""
print(np.delete(a, np.s_[::2]))
print("删除二维数组")
data = np.arange(12).reshape((3, 4))
print("数组元素:")
print(data)
# 行:  列: 2列开始
print(np.delete(data, np.s_[::2], axis=0))
print(np.delete(data, np.s_[::2], axis=1))

print('****************************unique**********************************************')

a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])
#
print('第一个数组:')
print(a)
print('\n')

print('第一个数组的去重值:')     # [2 5 6 7 8 9]
u = np.unique(a)
print(u)
print('\n')

print('去重数组的索引数组:')     # [a.index(2), a.index(5), ........a.index(9)]
u, indices = np.unique(a, return_index=True)
print(indices)
print('\n')

print('返回去重元素的重复数量:')
u, indices = np.unique(a, return_counts=True)
print(u)
print(indices)

运行结果:

***************append****************
第一个数组:
[[1 2 3]
 [4 5 6]]


向数组添加元素:
[1 2 3 4 5 6 7 8 9]


沿轴 0 添加元素:
[[1 2 3]
 [4 5 6]
 [7 8 9]]


沿轴 1 添加元素:
[[1 2 3 5 5 5]
 [4 5 6 7 8 9]]
******************************insert****************************************
第一个数组:
[[1 2]
 [3 4]
 [5 6]]


未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 1  2  3 11 12  4  5  6]


传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[  1   2]
 [ 11 100]
 [  3   4]
 [  5   6]]


沿轴 1 广播:
[[ 1 11  2]
 [ 3 12  4]
 [ 5 13  6]]
***********************delete******************************************
第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]


未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 0  1  2  3  4  6  7  8  9 10 11]


删除第二列:
[[ 0  2  3]
 [ 4  6  7]
 [ 8 10 11]]


删除第二行:
[[ 0  1  2  3]
 [ 8  9 10 11]]


包含从数组中删除的替代值的切片:
[ 2  4  6  8 10]
删除二维数组
数组元素:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[[4 5 6 7]]
[[ 1  3]
 [ 5  7]
 [ 9 11]]
****************************unique**********************************************
第一个数组:
[5 2 6 2 7 5 6 8 2 9]


第一个数组的去重值:
[2 5 6 7 8 9]


去重数组的索引数组:
[1 0 2 4 7 9]


返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]

10、numpy的统计函数

numpy.amin() 用于计算数组中的元素沿指定轴的最小值。
numpy.amax() 用于计算数组中的元素沿指定轴的最大值。
numpy.ptp()函数计算数组中元素最大值与最小值的差(最大值 - 最小值)。
numpy.percentile() 百分位数是统计中使用的度量,表示小于这个值的观察值的百分比。
numpy.median() 函数用于计算数组 a 中元素的中位数(中值)

平均值, 各个值的比重/权重一样. 语文: 100 数学:70 英语: 80 (100+70+80)/3
numpy.mean() 函数返回数组中元素的算术平均值。 如果提供了轴,则沿其计算。
#加权平均值, 各个值的比重/权重不一样. 语文: 100 (40%)数学:70(40%) 英语: 80(20%) (10040%+7040%+80*20%)/3
numpy.average() 函数根据在另一个数组中给出的各自的权重计算数组中元素的加权平均值。 average()

np.std() 标准差是一组数据平均值分散程度的一种度量。
标准差公式如下:std = sqrt(((x - x.mean())2))/n
np.var() 统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数,即 ((x - x.mean())
 2)/n。
标准差是方差的平方根。

二、案例一(Numpy学生身高体重统计分析)

需求1:
    获取所有男生的身高, 求平均值;获取所有女生的身高, 求平均值;并绘制柱状图显示
    1). 读取文件中的Sex和Height
    2). 根据布尔索引判断姓名, 获取男性的身高或者女性的身高  data['gender'] == 'M'
    3). 求平均值mean函数

需求2:
    获取所有男生的体重, 求平均值;获取所有女生的体重, 求平均值;并绘制柱状图显示
import numpy as np
def get_avg_height():
    fname = "doc/eg6-a-student-data.txt"
    # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('height', 'f2')])
    # 读取文件的第2列和第3列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 3))
    print(data)
    print(type(data))         # 通过np加载文件, 返回的是ndarray的数据类型
    print(data['gender'])     # 获取gender列信息
    print(data['height'])     # 获取height列信息


    # print(data['height'][data['gender'] == b'M'].mean())
    # print(data['height'][data['gender'] == b'F'].mean())

    # 判断是否性别为那男的表达式
    isMale = (data['gender'] == b'M')
    male_avg_height = data['height'][isMale].mean()
    # ~代表取反
    female_avg_height = data['height'][~isMale].mean()
    return male_avg_height, female_avg_height
def parser_weight(weight):
    # 对于体重数据的处理, 如果不能转换为浮点数据类型, 则返回缺失值;
    try:
        return  float(weight)
    except ValueError as e:
        return  -99
def get_avg_weight():
    fname = "doc/eg6-a-student-data.txt"
    # 定义读取列的数据类型
    dtype = np.dtype([('gender', '|S1'), ('weight', 'f2')])
    # 读取文件的第2列和第4列, 前9行忽略;
    data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,
                      usecols=(1, 4), converters={4:parser_weight})

    # 判断是否性别为男的平均身高
    isMale = data['gender'] == b'M'

    # 判断是否性别为男的平均体重
    is_weight_vaild = data['weight'] > 0
    male_avg_weight = data['weight'][isMale & is_weight_vaild].mean()
    female_avg_weight = data['weight'][~isMale & is_weight_vaild].mean()
    return  male_avg_weight, female_avg_weight
if __name__ == '__main__':
    print(get_avg_height())
    print(get_avg_weight())

运行结果:

三、案例二(基于Numpy的股价统计分析和应用)

#股票数据信息的获取
    1. 网络爬虫
    2. 网站下载: 专门的股票网站, Kaggle(数据分析和机器学习交流的网站)
    3. 使用已经开发好的股票API接口: tushare

data.csv文件中存储了股票的信息, 其中第4-8列,即EXCEL表格中的D-H列,(K线=)
分别为股票的开盘价,最高价,最低价,收盘价,成交量。
分析角度:
    1. 计算成交量加权平均价格
    概念:成交量加权平均价格,英文名VWAP(Volume-Weighted Average Price,成交量加权平均价格)是一个非常重要的经
    济学量,代表着金融资产的“平均”价格。
    某个价格的成交量越大,该价格所占的权重就越大。VWAP就是以成交量为权重计算出来的加权平均值。

    2. 计算最大值和最小值: 计算股价近期最高价的最大值和最低价的最小值
    3. 计算股价近期最高价的最大值和最小值的差值;----(极差)
    计算股价近期最低价的最大值和最小值的差值
    4. 计算收盘价的中位数
    5. 计算收盘价的方差
    6. 计算对数收益率, 股票收益率、年波动率及月波动率
     ***收盘价的分析常常是基于股票收益率的。
     股票收益率又可以分为简单收益率和对数收益率。
            简单收益率:是指相邻两个价格之间的变化率。  diff
            对数收益率:是指所有价格取对数后两两之间的差值。
            #[1, 2,3 4]   ======>[-1, ]
    ***使用的方法: NumPy中的diff函数可以返回一个由相邻数组元素的差值构成的数组。
    不过需要注意的是,diff返回的数组比收盘价数组少一个元素。
    ***在投资学中,波动率是对价格变动的一种度量,历史波动率可以根据历史价格数据计算得出。计算历史波动率时,需要用
    到对数收益率。
        年波动率等于对数收益率的标准差除以其均值,再乘以交易日的平方根,通常交易日取252天。
        月波动率等于对数收益率的标准差除以其均值,再乘以交易月的平方根。通常交易月取12月。
    7. 获取该时间范围内交易日周一、周二、周三、周四、周五分别对应的平均收盘价
    8. 平均收盘价最低,最高分别为星期几

代码:

import numpy as np

print("**********************************************")

# 收盘价,成交量
endPrice, countNum = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",  # 指定文件分隔符;
    usecols=(6, 7),
    unpack=True)
# print(endPrice, countNum)
VWAP = np.average(endPrice, weights=countNum)  # 价格的权重和成交量成正比
print("1. 计算成交量加权平均价格:", VWAP)

print("**********************************************")

# 最高价和最低价
highPrice, lowPrice = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",
    usecols=(4, 5),
    # 对于返回的数据进行解包, 有几列信息返回几个数据, 解包几个数据。
    unpack=True
)

print(highPrice, lowPrice)
# 最高价的最大值和最低价的最小值
print("2.最高价的最大值: ", highPrice.max())
print("2.最低价的最小值: ", lowPrice.min())

print("**********************************************")
# 计算股价近期最高价的最大值和最小值的差值;----(极差)
#     计算股价近期最低价的最大值和最小值的差值

print("3. 近期最高价的极差: ", np.ptp(highPrice))
print("3. 近期最低价的极差: ", np.ptp(lowPrice))

print("**********************************************")
# 计算收盘价的中位数
print("4. 计算收盘价的中位数:", np.median(endPrice))

print("**********************************************")
# 计算收盘价的方差
print("5. 计算收盘价的方差:", np.var(endPrice))

print("**********************************************")


def get_week(date):
    """根据传入的日期28-01-2011获取星期数, 0-星期一 1-"""
    from datetime import datetime
    # 默认传入的不是字符串, 是bytes类型;
    date = date.decode('utf-8')
    """
    Monday == 0 ... Sunday == 6
    """
    return datetime.strptime(date, "%d-%m-%Y").weekday()
# 星期数和收盘价
week, endPrice = np.loadtxt(
    fname="doc/data.csv",
    delimiter=",",
    usecols=(1, 6),
    converters={1: get_week},
    unpack=True
)
# print(week, endPrice)
allAvg = []
for weekday in range(5):
    # 依次判断获取星期一的平均收盘价, .......星期五
    average = endPrice[week == weekday].mean()
    allAvg.append(average)
    print("7. 星期%s的平均收盘价:%s" % (weekday + 1, average))

print(allAvg)

print("**********************************************")
# [12, 23, 34, 45, 56]

print("8.平均收盘价最低是星期", np.argmin(allAvg) + 1)
print("8. 平均收盘价最高是星期", np.argmax(allAvg) + 1)
#

print("***********************************************************")
# 简单收益率
simpleReturn = np.diff(endPrice)
print(simpleReturn)
# 对数收益率: 所有价格取对数后两两之间的差值。
logReturn = np.diff(np.log(endPrice))
print("6. 对数收益率:", logReturn)
# 年波动率等于对数收益率的标准差除以其均值,再乘以交易日的平方根,通常交易日取252天。
annual_vol = logReturn.std() / logReturn.mean() * np.sqrt(252)
print("6. 年波动率:", annual_vol)
#  月波动率等于对数收益率的标准差除以其均值,再乘以交易月的平方根。通常交易月取12月。
month_vol = logReturn.std() / logReturn.mean() * np.sqrt(12)
print("6. 月波动率:", month_vol)

 测试结果:

**********************************************
1. 计算成交量加权平均价格: 350.5895493532009
**********************************************
[344.4  340.04 345.65 345.25 344.24 346.7  353.25 355.52 359.   360.
 357.8  359.48 359.97 364.9  360.27 359.5  345.4  344.64 345.15 348.43
 355.05 355.72 354.35 359.79 360.29 361.67 357.4  354.76 349.77 352.32] [333.53 334.3  340.98 343.55 338.55 343.51 347.64 352.15 354.87 348.
 353.54 356.71 357.55 360.5  356.52 349.52 337.72 338.61 338.37 344.8
 351.12 347.68 348.4  355.92 357.75 351.31 352.25 350.6  344.9  345.  ]
2.最高价的最大值:  364.9
2.最低价的最小值:  333.53
**********************************************
3. 近期最高价的极差:  24.859999999999957
3. 近期最低价的极差:  26.970000000000027
**********************************************
4. 计算收盘价的中位数: 352.055
**********************************************
5. 计算收盘价的方差: 50.126517888888884
**********************************************
7. 星期1的平均收盘价:351.7900000000001
7. 星期2的平均收盘价:350.63500000000005
7. 星期3的平均收盘价:352.1366666666666
7. 星期4的平均收盘价:350.8983333333333
7. 星期5的平均收盘价:350.0228571428571
[351.7900000000001, 350.63500000000005, 352.1366666666666, 350.8983333333333, 350.0228571428571]
**********************************************
8.平均收盘价最低是星期 5
8. 平均收盘价最高是星期 3
***********************************************************
[  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]
6. 对数收益率: [ 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]
6. 年波动率: 129.27478991115134
6. 月波动率: 28.210071915112593

data.csv文件内容如下:

AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
AAPL,31-01-2011, ,335.8,340.04,334.3,339.32,13473000
AAPL,01-02-2011, ,341.3,345.65,340.98,345.03,15236800
AAPL,02-02-2011, ,344.45,345.25,343.55,344.32,9242600
AAPL,03-02-2011, ,343.8,344.24,338.55,343.44,14064100
AAPL,04-02-2011, ,343.61,346.7,343.51,346.5,11494200
AAPL,07-02-2011, ,347.89,353.25,347.64,351.88,17322100
AAPL,08-02-2011, ,353.68,355.52,352.15,355.2,13608500
AAPL,09-02-2011, ,355.19,359,354.87,358.16,17240800
AAPL,10-02-2011, ,357.39,360,348,354.54,33162400
AAPL,11-02-2011, ,354.75,357.8,353.54,356.85,13127500
AAPL,14-02-2011, ,356.79,359.48,356.71,359.18,11086200
AAPL,15-02-2011, ,359.19,359.97,357.55,359.9,10149000
AAPL,16-02-2011, ,360.8,364.9,360.5,363.13,17184100
AAPL,17-02-2011, ,357.1,360.27,356.52,358.3,18949000
AAPL,18-02-2011, ,358.21,359.5,349.52,350.56,29144500
AAPL,22-02-2011, ,342.05,345.4,337.72,338.61,31162200
AAPL,23-02-2011, ,338.77,344.64,338.61,342.62,23994700
AAPL,24-02-2011, ,344.02,345.15,338.37,342.88,17853500
AAPL,25-02-2011, ,345.29,348.43,344.8,348.16,13572000
AAPL,28-02-2011, ,351.21,355.05,351.12,353.21,14395400
AAPL,01-03-2011, ,355.47,355.72,347.68,349.31,16290300
AAPL,02-03-2011, ,349.96,354.35,348.4,352.12,21521000
AAPL,03-03-2011, ,357.2,359.79,355.92,359.56,17885200
AAPL,04-03-2011, ,360.07,360.29,357.75,360,16188000
AAPL,07-03-2011, ,361.11,361.67,351.31,355.36,19504300
AAPL,08-03-2011, ,354.91,357.4,352.25,355.76,12718000
AAPL,09-03-2011, ,354.69,354.76,350.6,352.47,16192700
AAPL,10-03-2011, ,349.69,349.77,344.9,346.67,18138800
AAPL,11-03-2011, ,345.4,352.32,345,351.99,16824200

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值