python(numpy模块)

什么是numpy?

快速, 方便的科学计算基础库(主要是数值的计算, 多维数组的运算);

数组和列表的区别

  • 数组: 存储的时同一种数据类型;
  • list:容器, 可以存储任意数据类型;
  • 数组是一种特殊的列表

numpy的操作

1. numpy中如何创建数组(矩阵)?

方法一:
# 导入模块时通常将模块起作np别名
import numpy as np
a=np.array([1,2,3,4,5])
b=np.array(range(1,6))
print(a,b)
方法二:
import numpy as np
c=np.arange(1,6)
print(c)

# 数组的类名: numpy.ndarray
print(type(c))

# 查看数据元素的类型
print(c.dtype)

python(numpy模块)

2. 修改数组的数据类型

print(c.astype('float'))
print(c.astype('bool'))
print(c.astype('?'))  # ?是bool类型的代号;

# 创建的时候指定数据类型
print(np.array([1,2,3,4], dtype=np.float))

python(numpy模块)

3. 修改浮点数的小数位数

a=np.array([1.2344435,4.45634562,8.23423525])
print(np.round(a,4))

python(numpy模块)

numpy读取数据

csv格式的文件是以逗号分隔开,但起始广义上,只要是以相同符号分隔的文件都叫做csv文件,
因此,在numpy读取csv格式的数据时,可以根据行、列来获取需要的数据。

import numpy as np

fname = "doc/eg6-a-student-data.txt"
dtype = np.dtype([('gender', '|S1'), ('height', 'f2')])
# fname: 文件的名称, 可以是文件名, 也可以是ugz或者bz2的压缩文件;
# dtype: 数据类型, 可选, 默认是float;
# delimiter: 分隔符字符串, 默认情况是任何的空格,
# skiprows: 跳过前xx行, 一般情况跳过第一行;
#  usecols: 读取指定的列, 可以是元组;
# unpack: 如果为True, 对返回的数组对象转置;
data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9, usecols=(1, 3), unpack=True)
print(data)

python(numpy模块)

numpy数组的转置

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)


# 1).
print(data.transpose())

# 2). 0轴 , 1 轴
print(data.swapaxes(1, 0))

# 3).
print(data.T)

python(numpy模块)

numpy的索引和切片

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)

# 取第一行的数据
print(data[0])

#  取第一列的数据
print(data.T[0])
print(data[:, 1])

# 获取多行
print(data[:2])

# 获取多行列
print(data.T[:2])
print(data[:, :2])


# 获取指定行的前几列;
print(data)
print(data[[0,2], :2])
print(data[:2, [0,2]])

python(numpy模块)

numpy中数值的修改

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)
# 按索引直接替换 
data[0] = 0
print(data)

data.T[:2] = 0
print(data)

python(numpy模块)

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)
# 布尔索引: 复杂的条件: data中所有大于8的数字都替换为0;
# 返回一个三行四列的数组, 存储的是Bool值
print(data>8)
data[data>8] = 0
print(data)

python(numpy模块)

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)
# 复杂的条件: data中所有大于8的数字都替换为0, 否则替换为1; a>b?a:b
print(np.where(data <= 8, 1, 0))

python(numpy模块)

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
print(data)

# 裁剪: 如果data<=8, 替换称8, 如果data>=10, 替换为10;
print(data.clip(8, 10))

python(numpy模块)

数组的拼接

竖直拼接(vertically)

import numpy as np

a=np.arange(12).reshape(2,6)
b=np.arange(12).reshape(2,6)
c=np.arange(12).reshape(2,6)

print(np.vstack((a,b,c)))

python(numpy模块)

水平拼接(horizontally)

import numpy as np

a=np.arange(12).reshape(2,6)
b=np.arange(12).reshape(2,6)
c=np.arange(12).reshape(2,6)

print(np.hstack((a,b,c)))

python(numpy模块)

数组的行列交换

行交换

import numpy as np

t4 = np.arange(12).reshape(2, 6)
# 行交换(第一行和第二行进行交换)
print("原数据:\n", t4)
t4[[0, 1], :] = t4[[1, 0], :]
print("替换后的数据:\n", t4)

python(numpy模块)

列交换

import numpy as np

t4 = np.arange(12).reshape(2, 6)

# 列交换(第3列和第5列进行交换)
print("原数据:\n", t4)
t4[:, [2, 4]] = t4[:, [4, 2]]
print("替换后的数据:\n", t4)

python(numpy模块)

numpy常用的方法

获取最大值和最小值的索引;

import numpy as np

# 将一维数组转换为3行4列的二维数组
data = np.arange(12).reshape((3, 4))
data[0, 0] = 80
print(data)

# 1. 获取最大值和最小值的位置;
# 获取当前数组里面最大值的索引;
max_item1 = np.argmax(data)
print(max_item1)

# 获取每一列的最大值对应的索引;
print(np.argmax(data, axis=0))
# 获取每一行的最大值对应的索引;
print(np.argmax(data, axis=1))

python(numpy模块)

创建特殊矩阵

# 在创建时默认的矩阵内数据的数据类型为float类型
# 2. 创建一个全为0的数组;
print(np.zeros((3, 3), dtype=np.int))

# 3. 创建一个全为1的数组;
print(np.ones((3, 4)))

# 4. 创建一个对角线全为1的正方形数组(方阵)
print(np.eye(3))

python(numpy模块)

numpy的深拷贝和浅拷贝

列表的深拷贝和浅拷贝

  • 浅拷贝: a= b[::] a = copy.copy(b)
  • 深拷贝: a = copy.deepcopy(b)

numpy中的深拷贝和浅拷贝

  • data1 = data: 完全不复制, 两个变量相互影响, 指向同一块内存空间;
  • data2 = data[::], 会创建新的对象data2,但是data的数据完全由data2保管, 两个的数据变化是一致的;
  • data3 = data.copy(), 深拷贝, 两个变量不湖影响;

numpy中的nan和inf

  • nan(not a number): 表示不是一个数字, 代表的是数据缺失
  • inf(infinity): inf代表正无穷, -inf代表负无穷

nan的特殊属性:

  • 两个nan的值是不相等的, 是float类型:
    python(numpy模块)
  • 如何判断有多少个缺失值:
    python(numpy模块)
  • 判断data里面的缺失值
    python(numpy模块)
import numpy as np

print(np.nan)
print(np.inf)
print(-np.inf)

python(numpy模块)

numpy的常用统计函数

  • 求和
  • 均值
  • 中值
  • 最大值
  • 最小值
  • 极差
  • 标准差: 代表的是数据的波动稳定情况, 数字越大, 越不稳定;
import numpy as np
data = np.arange(12, dtype=np.float).reshape(3, 4)
print(data.sum())
# 每一列数据的和;
print(data.sum(axis=0))
# 每一行数据的和;
print(data.sum(axis=1))



# - 均值

print(data.mean())
print(data.mean(axis=0))
print(data.mean(axis=1))



# - 中值
print(data)
print(np.median(data))
print(np.median(data, axis=0))
print(np.median(data, axis=1))


# - 最大值
print(data.max())
print(data.max(axis=0))
print(data.max(axis=1))

# - 最小值
# - 极差
print(np.ptp(data))
print(np.ptp(data, axis=0))
print(np.ptp(data, axis=1))


# - 标准差: 代表的是数据的波动稳定情况, 数字越大, 越不稳定;
print(data.std())
print(data.std(axis=0))
print(data.std(axis=1))

python(numpy模块)

numpy_学生身高体重统计分析案例

需求1:

获取所有男生的身高, 求平均值;获取所有女生的身高, 求平均值;并绘制柱状图显示

import numpy as np
from pyecharts import  Bar
fname = "doc/eg6-a-student-data.txt"
dtype = np.dtype([('gender', '|S1'), ('height', 'f2')])
# 不能将数组转置,即unpack=False
data = np.loadtxt(fname=fname, dtype=dtype, skiprows=9,usecols=(1, 3))
# 判断是否性别为那男的表达式
isMale = data['gender'] == b'M'
male_avg_height = data['height'][isMale].mean()
female_avg_height = data['height'][~isMale].mean()
print(male_avg_height, female_avg_height)

bar = Bar(title="不同性别身高的平均值")
bar.add("", ["男", '女'], [male_avg_height, female_avg_height])
bar.render()

python(numpy模块)

需求2:

获取所有男生的体重, 求平均值;获取所有女生的体重, 求平均值;并绘制柱状图显示
难点:需要将体重列中的空白项替换成np.nan

def parser_weight(weight):
    # 对于体重数据的处理, 如果不能转换为浮点数据类型, 则返回缺失值;
    try:
        return  float(weight)
    except ValueError as e:
        return  np.nan
fname='doc/eg6-a-student-data.txt'
dtype=np.dtype([('gender','|S1'),('weight','f2')])
# converters:将获取的第4列传递给parser_weight函数
# 处理后的数据再返回给data对象
data=np.loadtxt(fname=fname,dtype=dtype,converters={4:parser_weight},skiprows=9,usecols=(1,4))
# 将男生且不是缺失值的体重求平均值
male=data['weight'][(data['gender']==b'M') & (data==data)].mean()
# 将女生且不是缺失值的体重求平均值
female=data['weight'][(data['gender']==b'F') & (data==data)].mean()
# 绘制柱状图
bar=Bar('男女的平均体重')
bar.add('男女生平均体重',['男生','女生'],[male,female])

bar.render()

python(numpy模块)

案例1_基于numpy的股价统计分析应用

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

    某个价格的成交量越大,该价格所占的权重就越大。VWAP就是以成交量为权重计算出来的加权平均值。


    2. 计算最大值和最小值: 计算股价近期最高价的最大值和最低价的最小值

    3. 计算股价近期最高价的最大值和最小值的差值;----(极差)
    计算股价近期最低价的最大值和最小值的差值

    4. 计算收盘价的中位数

    5. 计算收盘价的方差

    6. 计算对数收益率, 股票收益率、年波动率及月波动率
     ***收盘价的分析常常是基于股票收益率的。
     股票收益率又可以分为简单收益率和对数收益率。
            简单收益率:是指相邻两个价格之间的变化率。
            对数收益率:是指所有价格取对数后两两之间的差值。
            # [1, 2,3 4]   ======>[-1, ]
    ***使用的方法: NumPy中的diff函数可以返回一个由相邻数组元素的差值构成的数组。
    不过需要注意的是,diff返回的数组比收盘价数组少一个元素。

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


    7. 获取该时间范围内交易日周一、周二、周三、周四、周五分别对应的平均收盘价


    8. 平均收盘价最低,最高分别为星期几
import numpy as np

params1=np.loadtxt(
    fname='doc/data.csv',
    delimiter=',',
    usecols=(6,7),
    unpack=True
)
endPrice,countNum=params1
print('1.成交量加权平均价格:',np.average(endPrice,weights=countNum))

params2=np.loadtxt(
    fname='doc/data.csv',
    delimiter=',',
    usecols=(4,5),
    unpack=True
)
highPrice,lowPrice=params2
print('2.最高价的最大值:',highPrice.max())
print('2.最低价的最小值:',lowPrice.min())

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

print('4.收盘价的中值:',np.median(endPrice))

print('5.收盘价的方差',np.var(endPrice))

# 取两两之间的差值
simpleRate=np.diff(endPrice)
print(simpleRate)
logRate=np.diff(np.log(endPrice))

annual_vol=logRate.std()/logRate.mean()*np.sqrt(252)

month_vol=logRate.std()/logRate.mean()*np.sqrt(12)
print('6.年波动率:',annual_vol)
print('6.月波动率:',month_vol)


def get_week(date):
    from datetime import datetime
    date=date.decode('utf-8')
    return datetime.strptime(date,'%d-%m-%Y').weekday()
params3=np.loadtxt(
    fname='doc/data.csv',
    delimiter=',',
    converters={1:get_week},
    usecols=(1,6),
    unpack=True
)
date,endPrice=params3
print(date)
day=['一','二','三','四','五']
endPriceAvg=[]
for weekday in range(5):
    endPriceAvg.append(np.mean(endPrice[date==weekday]))
    print('7.星期%s的平均收盘价:%s' %(day[weekday],np.mean(endPrice[date==weekday])))

print('8.平均收盘价最低为星期%s' %(day[int(np.argmin(endPriceAvg))]))
print('8.平均收盘价最高为星期%s' %(day[int(np.argmax(endPriceAvg))]))

print(type(np.argmin(endPriceAvg)))

python(numpy模块)