# 使用conda创建新的虚拟环境
# requirements.txt
matplotlib==2.2.2
numpy==1.14.2
pandas==0.20.3
TA-Lib==0.4.16 # 技术指标库
tables==3.4.2 # hdf5
jupyter==1.0.0 # 数据分析与展示的平台
# 执行命令 pip install -r requirements.txt
# pip list 查看已安装列表
# TA-Lib安装报错,https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib 下载
一个支持跨所有编程语言的交互式数据科学计算工具
web版的ipython
编程、写文档、记笔记、展示
.ipynb文件格式
交互式运行环境
为什么使用Jupyter Notebook
启动Jupyter Notebook
# 在终端输入 jupyter notebook 或者ipython notebook
创建文件
主页页面右上角News-Python3
运行代码快捷键
Shift+Enter
Cell
两种模式
常用快捷键
Shift+Enter 执行本单元代码,并跳转到下一单元
Ctrl+Enter 执行本单元代码,留在本单元
命令模式下
编辑模式下
cell行号前*,代表当前代码正在运行
什么是Matplotlib
Matplotlib专门用来开发2D图表(包括3D图表)
使用起来及其简单
以渐进、交互式方式实现数据可视化
matploltlib :画二维图表的python库
matlab 矩阵实验室
为什么要学习Matplotlib
Matplotlib快速上手
import matplotlib.pylab as plt
%matplotlib inline
plt.figure() # 画布
plt.plot([1,0,9], [4,5,6]) #([x1,x2,x3],[y1,y2,y3])
plt.show() # 展示
matplotlib.pyplot模块
import matplotlib.pylab as plt
折线图的绘制与显示
# 展示上海一周的天气
# 创建画布
plt.figure()
# 绘制图像
plt.plot([1,2,3,4,5,6,7],[17,17,18,15,11,11,12])
# 显示图像
plt.show()
设置画布属性
plt.figure(figsize(), dpi=)
# figsize:指定图的长宽
# dpi:图像的清晰度
# 返回fig对象
# 例:plt.figure(figsize=(20,8),dpi=80)
图片保存
# plt.savefig("test.png")
# 保存图片需要在show()之前
准备初始折线图
# 需求:画出某城市11点到12点1小时内每分钟的温度变化折线图,温度范围在15度~18度
# 准备数据 x,y
import random
x = range(60)
y_sh = [random.uniform(15,18) for i in x]
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y_sh)
plt.show()
添加自定义刻度
plt.xticks(x, **kwargs)
plt.yticks(y, **kwargs)
# x,y: 要显示的刻度值
# 例如
# 修改x轴刻度值
x_label = ["11点{}分".format(i) for i in x]
plt.xticks(x[::5], x_label[::5])
# 修改y轴刻度值
plt.yticks(range(0,40,5))
添加网格显示
# 添加网格显示
plt.grid(True, linestyle="--", alpha=0.5)
# grid(是否添加网格,linestyle风格 -- 虚线,透明度)
添加描述信息
# 添加描述信息
plt.xlabel("时间变化")
plt.ylabel("温度变化")
plt.title("某城市温度变化情况图")
中文不显示问题
原因:matplotlib不包含中文字体
解决:
安装字体
删除mapplotlib缓存文件
配置文件
查看配置文件路径
import matplotlib
matplotlib.matplotlib_fname()
# 配置文件增加内容
font.family : Microsoft YaHei, sans-serif
font.serif: Microsoft YaHei, DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
# C:\Windows\Fonts\Microsoft YaHei UI下的字体 复制到
# matplotlib根目录\mpl-data\fonts\ttf
多个plot
# 添加一个城市的温度变化
# y轴数据
y_bj = [random.uniform(1,3) for i in x]
# 添加图像
plt.plot(x, y_bj)
修改图像
# color 颜色
# linestyle 风格
plt.plot(x, y_bj, color = "b", linestyle="--")
颜色字符 | 风格字符 |
---|---|
r 红色 | - 实线 |
g 绿色 | – 虚线 |
b 蓝色 | -. 点划线 |
w 白色 | : 点虚线 |
c 青色 | ’ ’ 留空、空格 |
m 洋红 | |
y 黄色 | |
k 黑色 |
图例
plt.plot(x, y_bj, color = "b", linestyle="--", label = "北京")
# 显示图例
plt.legend()
subplots函数
figure, axes = plt.subplots(nrows=1,ncols=2,**fig_kw)
axes[0] # 第一个
axes[1] # 第二个
# 需求:画出某城市11点到12点1小时内每分钟的温度变化折线图,温度范围在15度~18度
# 准备数据 x,y
import random
x = range(60)
y_sh = [random.uniform(15,18) for i in x]
y_bj = [random.uniform(1,3) for i in x]
# 画布
# plt.figure(figsize=(20,8),dpi=80)
figure, axes = plt.subplots(nrows=1,ncols=2,figsize=(20, 8), dpi=80)
axes[0].plot(x,y_sh, label="上海")
axes[1].plot(x, y_bj, color = "b", linestyle="--", label = "北京")
# 修改x轴刻度值
x_label = ["11点{}分".format(i) for i in x]
axes[0].set_xticks(x[::5], x_label[::5])
# 修改y轴刻度值
axes[0].set_yticks(range(0,40,5))
axes[1].set_xticks(x[::5], x_label[::5])
axes[1].set_yticks(range(0,40,5))
# 添加网格显示
axes[0].grid(True, linestyle="--", alpha=0.5)
axes[1].grid(True, linestyle="--", alpha=0.5)
# 添加描述信息
axes[0].set_xlabel("时间变化")
axes[0].set_ylabel("温度变化")
axes[0].set_title("上海温度变化情况图")
axes[1].set_xlabel("时间变化")
axes[1].set_ylabel("温度变化")
axes[1].set_title("北京温度变化情况图")
# 显示图例
plt.legend()
plt.show()
呈现公司产品(不同区域)每天活跃用户数
呈现app每天下载量
呈现产品新功能上线后,用户点击次数随着时间的变化
拓展:画各种数学函数图像
import matplotlib.pylab as plt
import numpy as np
# 准备x,y数据
x = np.linspace(-10,10,1000) # 生成-1到1之间等距离的1000个数据
y = np.sin(x)
plt.figure(figsize=(20,8),dpi=80)
plt.plot(x,y)
plt.grid(linestyle='--')
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CvxvxlQg-1661236390017)(.\image\sin函数曲线.png)]
# 探究房屋面积和房屋价格的关系
x = [1,2,3,4,5,6]
y = [7,8,9,10,11,12]
# 创建画布
plt.figure(figsize=(20,8),dpi=80)
# 绘制图像
plt.scatter(x,y)
# 显示图像
plt.show()
# 对比电影票房收入
# 准备数据
movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案']
tickets = [11111,22222,33333]
# 创建画布
plt.figure(figsize=(20,8),dpi=80)
# 绘制柱状图
plt.bar(movie_name, tickets,width=0.1)
# 显示图像
plt.show()
# 对比相同时间电影票房收入
movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案']
first_day = [11111,22222,33333]
first_weekend = [22222,33333,44444]
# 创建画布
plt.figure(figsize=(20,8),dpi=80)
# 绘制柱状图
plt.bar(range(3), first_day,width=0.2,label='首日票房')
plt.bar([0.2,1.2,2.2], first_weekend,width=0.2,label='首周票房')
plt.legend()
plt.xticks([0.1,1.1,2.1],movie_name)
# 显示图像
plt.show()
# 准备数据
time = [131, 98, 125, 131, 124, 139, 131, 117, 128, 108, 135, 138, 131, 102, 107, 114, 119, 128, 121, 142, 127, 130, 124, 101, 110, 116, 117, 110, 128, 128, 115, 99, 136, 126, 134, 95, 138, 117, 111,78, 132, 124, 113, 150, 110, 117, 86, 95, 144, 105, 126, 130,126, 130, 126, 116, 123, 106, 112, 138, 123, 86, 101, 99, 136,123, 117, 119, 105, 137, 123, 128, 125, 104, 109, 134, 125, 127,105, 120, 107, 129, 116, 108, 132, 103, 136, 118, 102, 120, 114,105, 115, 132, 145, 119, 121, 112, 139, 125, 138, 109, 132, 134,156, 106, 117, 127, 144, 139, 139, 119, 140, 83, 110, 102,123,107, 143, 115, 136, 118, 139, 123, 112, 118, 125, 109, 119, 133,112, 114, 122, 109, 106, 123, 116, 131, 127, 115, 118, 112, 135,115, 146, 137, 116, 103, 144, 83, 123, 111, 110, 111, 100, 154,136, 100, 118, 119, 133, 134, 106, 129, 126, 110, 111, 109, 141,120, 117, 106, 149, 122, 122, 110, 118, 127, 121, 114, 125, 126,114, 140, 103, 130, 141, 117, 106, 114, 121, 114, 133, 137, 92,121, 112, 146, 97, 137, 105, 98, 117, 112, 81, 97, 139, 113,134, 106, 144, 110, 137, 137, 111, 104, 117, 100, 111, 101, 110,105, 129, 137, 112, 120, 113, 133, 112, 83, 94, 146, 133, 101,131, 116, 111, 84, 137, 115, 122, 106, 144, 109, 123, 116, 111,111, 133, 150]
plt.figure(figsize=(20,8),dpi=80)
# 组距
distance = 2
# 组数
group_num = int((max(time) - min(time)) / distance)
# 绘制直方图
plt.hist(time, bins=group_num,density=True)
# 刻度
plt.xticks(range(min(time),max(time) + 2,2))
# 网格
plt.grid(linestyle="--", alpha=0.5)
plt.show()
# 准备数据
movie_name = ['雷神3:诸神黄昏','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其它']
place_count = [60605,54546,45819,28243,13270,9945,7679,6799,6101,4621,20105]
plt.figure(figsize=(20,8),dpi=80)
plt.pie(place_count,labels=movie_name,colors=['b','r','g','y','c','m','y','k','c','g','y'], autopct="%1.2f%%")
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IX3X2HkK-1661236390019)(.\image\image-20220822135930303.png)]
Numpy(Numerical Python)是一个开源的Python科学计算库,用于快速处理任意维度的数组。是一个高效的运算工具
Numpy:数值计算库
Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务,使用Numpy比直接使用python要简介的多
Numpy使用ndarray对象来处理多维数组,该对象是一个快速而灵活的大数据容器
ndarray属性
属性名称 | 属性解释 | 示例 |
---|---|---|
ndarray.shape | 数组维度的元组 | (8, 5) 表示二维数组,8行5列 |
ndarray.ndim | 数组维度 | |
ndarray.size | 数组中的元素数量 | |
ndarray.itemsize | 一个数组元素的长度 | |
ndarray.dtype | 数组元素的类型 |
ndarray的形状
ndarray的类型
ndarray.方法()
numpy.函数名()
生成数组的方法
生成0和1
# 生成0和1的数组
np.zeros(shape=(3,4))
np.ones(shape=(2,3),dtype=np.int32)
从现有数组中生成
# 深拷贝
data1 = np.array(score)
data3 = np.copy(score)
# 浅拷贝
data2 = np.asarray(score)
生成固定范围的数组
# 生成[-10,10]等距离的数组
np.linspace(-10,10,1000)
# 生成[a,b)范围c步长的数组
np.arange(a,b,c)
生成随机数组
均匀分布
# np.random.uniform(low,high,size)
x = np.random.uniform(-1,1,size=100000)
正态分布
# np.random.normal(loc=μ,scale=σ,size)
x2 = np.random.normal(loc=1.75,scale=0.1,size=10000)
数组的索引、切片
案例:随机生成8只股票2周的加以日涨幅数据
# 案例:随机生成8只股票2周的加以日涨幅数据
stock_change = np.random.normal(loc=0,scale=1,size=(8,10))
# 前三日数据
# 切片
stock_change[0,:3]
a1[1,0,2]
形状修改
# ndarray.reshape(shape) 修改形状,数据排列未改变,不修改原始数据,返回新的ndarray
stock_change.reshape(10,8)
# ndarray.resize(shape) 修改形状,数据排列未改变,原始数据改变
stock_change.resize((10,8))
# ndarray.T 转置 行变列、列边行
类型修改
ndarray.astype(type)
stock_change.astype(np.int32)
ndarray.tobytes()
# 序列化
ndarray.tobytes()
数组的去重
temp = np.array([[1, 2, 3, 4],[3, 4, 5, 6]]
np.unique(temp)
# 或者 flatten() 转一维数组
set(temp.flatten())
逻辑运算
stock_change = np.random.normal(loc=0,scale=1,size=(8,10))
# 逻辑判断,如果涨跌幅>0.5就标记为True,否则为False
stock_change > 0.5
# 布尔值条件索引,操作统一条件的数据
stock_change[stock_change > 0.5]
# 条件修改
stock_change[stock_change > 0.5] = 1.1
通用判断函数
np.all(布尔值)
只要有一个False就返回False,只有全是True才返回True
np.all(stock_change[0:2,0:5] > 0)
np.any()
只要有一个True就返回True,全是False才返回False
np.any(stock_change[:5,:] > 0)
三元运算符
# 前四个股票前四天的涨跌幅,大于0的置为1,否则为0
temp = stock_change[:4,:4]
np.where(temp > 0,1,0)
复合逻辑运算符
np.logical_and()
np.logical_or()
np.logical_and(temp > 0.5, temp < 1)
np.logical_or(temp > 1, temp < 0.5)
统计运算
统计指标函数(np.函数名())
axis=0 按列最大值,axis=1 按行最大值
最小值 min
np.max(temp,axis=0)
最大值 max
平均值 mean
标准差 std
方差 var
中间值 median
返回最大值、最小值所在位置
数组间运算
数组与数的运算
arr = np.array([[1, 2, 3, 2, 1, 4], [5, 6, 1, 2, 3, 1]])
# 直接运算即可
arr + 1
arr / 10
数组与数组的运算
广播机制
矩阵运算
什么是矩阵
两种方法存储矩阵
矩阵乘法运算
形状
运算规则
运算方法
# ndarray存储矩阵
data = np.array([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
# matrix存储矩阵
data_mat = np.mat([[80, 86],
[82, 80],
[85, 78],
[90, 90],
[86, 82],
[82, 90],
[78, 80],
[92, 94]])
weights = np.array([[0.3],[0.7]])
weights_mat = np.mat([[0.3],[0.7]])
np.matmul(data,weights)
np.dot(data,weights)
data @ weights
data_mat * weights_mat
合并
numpy.hstack(tup) 水平拼接
numpy.vstack(tup) 垂直拼接
a = np.array([1,2,3])
b = np.array([2,3,4])
np.hstack((a,b))
np.vstack((a,b))
np.concatenate((a,b), axis=0) axis = 0 垂直拼接,axis = 1 水平拼接
分割
IO操作
数据处理
DataFrame
import pandas as pd
# 基本
pd.DataFrame(stock_change)
# 添加行、列索引
stock = ['股票{}'.format(i) for i in range(10)]
date = pd.date_range(start='20220101',periods=5,freq='B')
pd.DataFrame(stock_change,index=stock,columns=date)
属性
方法
DataFrame索引的设置
修改行列索引值
只能整体修改
stock_ = ["股票_{}".format(i) for i in range(10)]
data.index = stock_
重设索引
# 不删除原索引
data.reset_index()
# 删除原索引
data.reset_index(drop=True)
设置新索引
df.set_index("month")
df.set_index("month",drop=False)
# 列表设置多个索引
new_df = df.set_index(["year","month"])
# new_df.index 类型是MultiIndex
MultiIndex
Panel
Series
带索引的一维数组
创建
pd.Series(np.arange(10))
pd.Series(np.arange(3),index=['a','b','c'])
属性
小结
直接索引
# 直接索引
data = pd.read_csv("./stock_day.csv")
data["open"]["2018-02-27"] # 先列后行
按名字索引
data.loc["2018-02-27"]["open"]
data.loc["2018-02-27","open"]
按数字索引
data.iloc[1,0]
组合索引
data.ix[] 已经废弃
# 通过数字获取名字索引,再通过名字索引方法获取
data.loc[data.index[i],['open','name']]
# 通过名字获取索引数字,再用数字索引方法
data.iloc[0,data.columns.get_indexer(['open','name'])]
data['open'] = 100
内容排序(dataframe)
# 按某字段排序
data.sort_values(by='high',ascending=False)
# 按多个字段排序
data.sort_values(by=['high','p_change'],ascending=False
索引排序(dataframe)
data.sort_index()
Series排序
data.sort_values()
data.sort_index()
算数运算
算数运算符
+、-、*、/ ...
算数运算函数
逻辑运算
逻辑运算符
# > < | &
data[data['open'] > 2] # 布尔索引值
data[(data['open'] > 2) & (data['low'] > 15)]
逻辑运算函数
query() 条件查询函数
data.query("open > 2 & low > 15")
isin() 是否包含
data[data['turnover'].isin([4.19,2.39])]
统计运算
min
max
mean 平均值
median
var
std
describe()
axis=1 按行,默认axis=0 按列
idmax() 最大值索引
idmin() 最小值索引
累计统计函数
cumsum 计算前1/2/3/4…/n个数的和
data['p_change'].cumsum()
# 画图
data['p_change'].sort_index().cumsum().plot()
cummax 计算前1/2/3/4…/n个数的最大值
data['p_change'].cummax()
cummin 计算前1/2/3/4…/n个数的最小值
cumprod 计算前1/2/3/4…/n个数的积
自定义运算
apply(func, axis=0)
func:自定义函数
axis:0 默认按列,axis=1 按行
data.apply(lambda x: x.max() - x.min())
读取csv文件-pd.read_csv()
usecols=[] 选择读取的列
name=[] 指定数据列名称
pd.read_csv('stock_day2.csv',names=["open", "high", "close", "low", "volume", "price_change", "p_change", "ma5", "ma10", "ma20", "v_ma5", "v_ma10", "v_ma20", "turnover"])
存储csv文件-DataFrame.to_csv()
参数
columns=[], 保存列
data[:10].to_csv('test.csv',columns=['open'])
index=False 不保存行索引
data[:10].to_csv('test.csv',columns=['open'],index=False)
mode=“a” 写入模式, a 追加
data[:10].to_csv('test.csv',columns=['open'],index=False,mode='a')
header=False 不保存列索引
data[:10].to_csv('test.csv',columns=['open'],index=False,mode='a',header=False)
读取
pd.read_json(path,orient=‘records’,lines=True)
sa = pd.read_json('./Sarcasm_Headlines_Dataset.json',orient='records',lines=True)
存储
思路
如何处理nan
判断数据中是否存在NaN
pd.isnull(df)
# 判断是否存在缺失值
np.any(pd.isnull(movie)) # 返回True,说明数据存在缺失值
pd.isnull(movie).any()
pd.notnull(df)
np.all(pd.notnull(movie)) # 返回False,说明数据存在缺失值
pd.isnull(movie).any()
删除缺失值样本
df.dropna(inplace=False)
# 缺失值处理
# 删除
data1 = movie.dropna()
替换/插补
# 替换
# Revenue (Millions) True
# Metascore True
movie['Revenue (Millions)'].fillna(movie['Revenue (Millions)'].mean(),inplace=True)
movie['Metascore'].fillna(movie['Metascore'].mean(),inplace=True)
缺失值不是nan,有默认标记的情况
分组
自动分组 sr = pd.qcut(data, bins)
data 数据
bins 组数
# 准备数据
data = pd.Series([165,174,160,180,159,163,192,184], index=['No1:165', 'No2:174','No3:160', 'No4:180', 'No5:159', 'No6:163', 'No7:192', 'No8:184'])
sr = pd.qcut(data,3)
pd.get_dummies(sr, prefix='height')
自定义分组 sr = pd.cut(data, [])
[] 分组区间列表
bins = [150,165,180,195]
sr2 = pd.cut(data,bins)
pd.get_dummies(sr2,"身高")
sr.value_counts()
将分组好的结果转换成one-hot编码
按方向拼接
按索引拼接
pd.merge(left, right, how=‘inner’, on[索引])
# 内连接
pd.merge(left, right, on=['key1','key2']) # 默认how = 'inner'
# 左连接
pd.merge(left, right, on=['key1','key2'],how='left')
# 右连接
pd.merge(left, right, on=['key1','key2'],how='right')
# 外连接
pd.merge(left, right, on=['key1','key2'],how='outer')
作用
使用crosstab(交叉表)实现
pd.crosstab(value1,value2)
data = pd.crosstab(stock['weekday'],stock['pona'])
data.div(data.sum(axis=1),axis=0).plot(kind='bar',stacked=True)
使用pivot_table(透视表)实现
pivot_table(data, index=)
# 透视表
stock.pivot_table(['pona'],index=['weekday'])
什么是分组与聚合
分组API
DataFrame
DataFrame.groupby(by=key, as_index=False)
col =pd.DataFrame({'color': ['white','red','green','red','green'], 'object': ['pen','pencil','pencil','ashtray','pen'],'price1':[5.56,4.20,1.30,0.56,2.75],'price2':[4.75,4.12,1.60,0.75,3.15]})
col.groupby(by='color')['price1'].max()
Series
col['price1'].groupby(col['color']).max()
#星巴克数据读取
sbs = pd.read_csv('directory.csv')
# 按国家分组
sbs.groupby(by='Country').count()['Brand'].sort_values(ascending=False)[:10].plot(kind='bar',figsize=(20,8))
# 按国家、城市分组
sbs.groupby(by=['Country','City']).count()
# 需求:
# 准备数据