数据分析
一.NumPy
NumPy是python语言的一个扩展程序库,支持大量的纬度数组和矩阵运算,此外也针对数组运算提供了大量的数学函数库
(1)一维数组创建
import numpy as np
np.array([1,2,3,4,5])
(2)二维数组的创建
import numpy as np
np.array([[1,2,3],[4,5,6]])
注:
-
numpy默认ndarray的所有元素的类型都是相同的
-
如果传进来的列表包含不通过的类型,则统一为同一类型.优先级:str>float>int
2.图片的操作
注:对图片的操作其实就是对图片对应数组的操作
(1)使用matplotlib.pyplot将图片转化为一个数组
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png') #数组
plt.imshow(img_arr) #图片
图片是一个三维数组,三个维度分别表示[像素,像素,颜色]
(2)改变图片的三个维度
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png')
plt.imshow(img_arr-0.1)
3.创建数组的其他方法
(1).np.linspace(开始,结束,一共有几个数) #获取由等差数列组成的一维数组
import numpy as np
arr=np.linspace(1,100,num=50)
arr
array([ 1. , 3.02040816, 5.04081633, 7.06122449,
9.08163265, 11.10204082, 13.12244898, 15.14285714,
17.16326531, 19.18367347, 21.20408163, 23.2244898 ,
25.24489796, 27.26530612, 29.28571429, 31.30612245,
33.32653061, 35.34693878, 37.36734694, 39.3877551 ,
41.40816327, 43.42857143, 45.44897959, 47.46938776,
49.48979592, 51.51020408, 53.53061224, 55.55102041,
57.57142857, 59.59183673, 61.6122449 , 63.63265306,
65.65306122, 67.67346939, 69.69387755, 71.71428571,
73.73469388, 75.75510204, 77.7755102 , 79.79591837,
81.81632653, 83.83673469, 85.85714286, 87.87755102,
89.89795918, 91.91836735, 93.93877551, 95.95918367,
97.97959184, 100. ])
(2).np.arrange(开始,结束,公差) #获取由等差数列组成的一维数组
import numpy as np
np.arange(1,100,2)
array([ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33,
35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67,
69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99])
(3).np.random系列函数
-
np.random.randint(1,1000,size=(5,6)) #随机数最小值,随机数最大值,数组的形状是5行6列
-
np.random.random(size=(3,4)) #随机数在0~1之间,数组的形状是3行4列
-
np.random.randn(5,6) #随机数呈正态分布,,数组的形状是3行4列
4.ndarray数组的属性
ndim:维度
3
shape:形状
img_arr.shape
(231, 230, 3)#像素,像素,颜色
size:总长度
159390
dtype:元素类型
dtype('float32')
5.将得到的随机数组固定保存
np.random.seed(2) #固定时间种子,随机因子是当前系统的时间
np.random.random(size=(3,4))
6.数组的索引和切片操作
取数组的行
arr=np.random.randint(1,100,size=(5,6))
arr[[0,1]] #取前两行
取数组的列
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr[:,0:2] #取数组的前两列
取数组的指定行和指定列
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr[0:2,0:2] #前两行的前两列
行反转
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr[::-1,:]
列反转
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr[::,::-1]
行和列同时反转
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr[::-1,::-1]
例:将图片倒置
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png')
img=img_arr[::-1,::-1]
plt.imshow(img)
7.变形
将五行六列的数组变成六行五列
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr.reshape((6,5))
注:变形前和变形后数组的总长度一定要相等
8.级联
axis=1是行 axis=0是列
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
np.concatenate((arr,arr),axis=1)
图片拼接
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png')
arr3=np.concatenate((img_arr,img_arr,img_arr),axis=1)
arr9=np.concatenate((arr3,arr3,arr3),axis=0)
plt.imshow(arr9)
注:
-
级联的参数是列表,第一个参数是元组
-
维度必须相同
-
形状相符(拼接的两个行数,或列数相同)
-
可通过axis参数改变级联的方向
8.切割
方式一
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png')
plt.imshow(img_arr[20:160,30:190])
方式二
import matplotlib.pyplot as plt
img_arr=plt.imread('nv.png')
img_new=np.split(img_arr,[100],axis=0)[0] #切哪个数组,在哪里切,0是横着切,1是竖着切
plt.imshow(img_new)
9.聚合操作(0代表列)
常见聚合操作
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr.sum() #求所有数的和
arr.sum(axis=0) #列的和
arr.sum(axis=1) #行的和
arr.max() #最大值
arr.min() #最小值
arr.mean() #平均值
其他聚合操作
Function Name NaN-safe Version Description
np.sum np.nansum Compute sum of elements
np.prod np.nanprod Compute product of elements
np.mean np.nanmean Compute mean of elements
np.std np.nanstd Compute standard deviation
np.var np.nanvar Compute variance
np.min np.nanmin Find minimum value
np.max np.nanmax Find maximum value
np.argmin np.nanargmin Find index of minimum value
np.argmax np.nanargmax Find index of maximum value
np.median np.nanmedian Compute median of elements
np.percentile np.nanpercentile Compute rank-based statistics of elements
np.any N/A Evaluate whether any elements are true
np.all N/A Evaluate whether all elements are true
np.power 幂运算
10.排序
方式一
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr
np.sort(arr,axis=0) #0代表对列排序
方式二
np.random.seed(2)
arr=np.random.randint(1,100,size=(5,6))
arr
arr.sort(axis=0) #0代表对列排序
区别
-
np.sort() #不改变输入
-
arr.sort() #改变输入,相对节省空间
二.Pandas
1.Series
Series是一种类似于一维数组的对象,由下面两部分组成
-
values:一维数组(ndarray类型)
-
index:相关数据的索引标签
(1)创建Series
使用列表创建Series
import pandas as pd
from pandas import Series,DataFrame
Series(data=[1,2,3,4,5])
使用numpy创建Series
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
arr=np.arange(1,10,2)
Series(data=arr)
注:index索引标签的使用
import pandas as pd
from pandas import Series,DataFrame
import numpy as np
arr=np.arange(1,10,2)
Series(data=arr,index=[11,22,33,44,55],name='aaa')
使用字典创建Series
import pandas as pd
from pandas import Series,DataFrame
dic={
"a":1,
"b":2
}
Series(data=dic) #字典的key会自动作为显示索引的index
(2)NaN和None的区别
None的数据类型Nonetype NaN的数据类型是浮点型
(3)Series的索引和切片
索引
import pandas as pd from pandas import Series,DataFrame dic={ "a":1, "b":2 } s=Series(data=dic) s["a"] #返回值是元素类型 s[["a","b"]] #返回值是Series类型
显式索引和隐式索引
-
显示索引
使用index中的元素作为索引值
使用s.lod[]获取
-
隐式索引
使用整数作为索引值
使用s.iloc[]获取
切片
import pandas as pd from pandas import Series,DataFrame dic={ "a":1, "b":2 } s=Series(data=dic) s[0:1]#或s.iloc[0:1]
(4)Series的属性
shape:形状 img_arr.shape (231, 230, 3)#像素,像素,颜色 size:总长度 159390 index:得到所有显示索引 values:得到所有值
(5)读取前n个和后n个值
import pandas as pd from pandas import Series,DataFrame import numpy as np arr=np.arange(1,30,3) s=Series(data=arr) s.head(6) #获取前n个值 s.tail(6) #获取后n个值
(6)对Series去重
import pandas as pd from pandas import Series,DataFrame data=[1,2,3,5,4,1,2,6,5,4,5,5,5,2,356,4,2] s=Series(data=data) s.unique() #没有参数 #结果:array([ 1, 2, 3, 5, 4, 6, 356], dtype=int64)
(7)查找空值
import pandas as pd from pandas import Series,DataFrame s1=Series(data=[1,2,3,4,5],index=['a','b','c','d','e']) s2=Series(data=[1,2,3,4,5],index=['a','b','f','d','e']) s=s1+s2 #使得两个Series进行相加:索引与之对应的元素会进行算数运算,不对应的就补空 s.isnull() #为空的是true s.notnull() #不为空是true pd.isnull(s) #为空的是true pd.notnull(s) #不为空是true
去除空值
import pandas as pd from pandas import Series,DataFrame s1=Series(data=[1,2,3,4,5],index=['a','b','c','d','e']) s2=Series(data=[1,2,3,4,5],index=['a','b','f','d','e']) s=s1+s2 s[[True,True,False,True,True,False]] #True的显示,False的不显示
(8)Series的运算
+-*/
import pandas as pd from pandas import Series,DataFrame s1=Series(data=[1,2,3,4,5],index=['a','b','c','d','e']) s2=Series(data=[1,2,3,4,5],index=['a','b','f','d','e']) s=s1-s2 s=s1+s2 s=s1*s2 s=s1/s2 s
注:索引与之对应的元素会进行算数运算,不对应的就补空
函数
import pandas as pd from pandas import Series,DataFrame s1=Series(data=[1,2,3,4,5],index=['a','b','c','d','e']) s2=Series(data=[1,2,3,4,5],index=['a','b','f','d','e']) s1.add(s2) #+ s1.sub(s2) #- s1.mul(s2) #* s1.div(s2) #/
2.DataFrame
DataFrame是一个【表格型】的数据结构。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
-
行索引:index
-
列索引:columns
-
值:values
(1)DataFrame的创建
使用ndarray创建DataFrame
import pandas as pd from pandas import Series,DataFrame DataFrame(data=np.random.randint(0,100,size=(5,6)))
0 | 1 | 2 | 3 | 4 | 5 | |
---|---|---|---|---|---|---|
0 | 81 | 99 | 70 | 23 | 92 | 81 |
1 | 46 | 56 | 79 | 76 | 13 | 50 |
2 | 94 | 92 | 62 | 85 | 51 | 59 |
3 | 85 | 54 | 34 | 34 | 15 | 71 |
4 | 0 | 91 | 35 | 84 | 25 | 60 |
使用字典创建
import pandas as pd from pandas import Series,DataFrame dic={ "张三":[99,88,77,66], "李四":[89,98,78,98] } DataFrame(data=dic,index=['语文','数学','英语','物理'])
张三 | 李四 | |
---|---|---|
语文 | 99 | 89 |
数学 | 88 | 98 |
英语 | 77 | 78 |
物理 | 66 | 98 |
(2)DataFrame的属性
import pandas as pd
from pandas import Series,DataFrame
dic={
"张三":[99,88,77,66],
"李四":[89,98,78,98]
}
df=DataFrame(data=dic,index=['语文','数学','英语','物理'])
df.values
#获取里面的所有值
#array([[99, 89],
# [88, 98],
# [77, 78],
# [66, 98]], dtype=int64)
df.index
获取所有的列索引
#Index(['语文', '数学', '英语', '物理'], dtype='object')
df.columns
#获取所有的行索引
#Index(['张三', '李四'], dtype='object')
df.shape
#获取数组的形状
#(4, 2)
(3)DataFrame的索引
列索引
获取一列
import pandas as pd from pandas import Series,DataFrame dic={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df=DataFrame(data=dic,index=['语文','数学','英语','物理']) df["张三"] #获取一列,方式一 df.张三 #方式二
获取多列
import pandas as pd from pandas import Series,DataFrame dic={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df=DataFrame(data=dic,index=['语文','数学','英语','物理']) df["张三"] #获取一列,方式一 df.张三 #方式二 df[["张三","李四"]]
修改列索引
import pandas as pd
from pandas import Series,DataFrame
dic={
"张三":[99,88,77,66],
"李四":[89,98,78,98]
}
df=DataFrame(data=dic,index=['语文','数学','英语','物理'])
df.columns=["san","si"] #修改列索引
行索引
import pandas as pd from pandas import Series,DataFrame dic={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df=DataFrame(data=dic,index=['语文','数学','英语','物理']) df.iloc[0] #使用.iloc[]加整数来进行行索引 df.loc["数学"] #使用.loc[]加index来进行行索引 df.iloc[[0,1]] #批量取行
切片:获取指定格子的数值
import pandas as pd from pandas import Series,DataFrame dic={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df=DataFrame(data=dic,index=['语文','数学','英语','物理']) df.iloc[0,1] #取出第0行第1列的数 df.iloc[0:2,0:2]#取出前两行的前两列
(4)DataFrame的运算
-
在运算中自动对齐不同索引的数据
-
如果索引不对应,则补NaN
import pandas as pd from pandas import Series,DataFrame dic1={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df1=DataFrame(data=dic1,index=['语文','数学','英语','物理']) dic2={ "张三":[99,88,77,66], "李四":[89,98,78,98] } df2=DataFrame(data=dic2,index=['语文','数学','英语','物理']) df=df1+df2 #+ df=df1-df2 #- df=df1*df2 #* df=df1/df2 #/
张三 | 李四 | |
---|---|---|
语文 | 1.0 | 1.0 |
数学 | 1.0 | 1.0 |
英语 | 1.0 | 1.0 |
物理 | 1.0 | 1.0 |
3.通过DataFrame做数据清洗
(1)删除重复数据
四.案例
案例一:金融量化分析
注:toshare模块可以用来获取股票的历史行情数据
目的1:找出茅台股票所有收盘价比开盘价上涨3%以上的日期
import tushare as ts
import pandas as pd
from pandas import Series,DataFrame
df=ts.get_k_data("600519",start="1999-01-01") #获取股票代码为600519的数据,从1999-01-01开始
#将获取到的数据存储到本地
df.to_csv('./maotai.csv')
#将date列的数据类型转成时间序列,再把这一列作为行索引
df=pd.read_csv("./maotai.csv",index_col="date",parse_dates=["date"])
#删除数据中没有用的列
df.drop(labels="Unnamed: 0",axis=1,inplace=True) #注:在drop系列的函数中,0表示行,1表示列
# df["date"].dtype #获取date这一列的数据的数据类型,字符串用O表示
#所有收盘价比开盘价上涨3%以上的日期
s=(df["close"]-df["open"])/df["open"]>0.03
s.index
# df.head()
目的2:输出所有股票开盘比前日收盘跌幅超过2%的日期
import tushare as ts
import pandas as pd
from pandas import Series,DataFrame
df=ts.get_k_data("600519",start="1999-01-01")
df.to_csv('./maotai.csv')
df=pd.read_csv("./maotai.csv",index_col="date",parse_dates=["date"])
df.drop(labels="Unnamed: 0",axis=1,inplace=True)
#将close列向下移动一位
# df["close"].shift(1)
s1=(df["open"]-df["close"].shift(1))/df["open"]<=-0.02
df.loc[s1] #取得true所对用行数据
df.loc[s1].index #获得这些行数据的行索引
目的三:从2010年开始,每月的第一个交易日根据开盘价买入一手股票,每年的最后一个交易日卖出所有的股票,到今天为止,收益如何?
import tushare as ts
import tushare as ts
import pandas as pd
from pandas import Series,DataFrame
df=ts.get_k_data("600519",start="2010-01-01")
df.to_csv('./maotai.csv')
df=pd.read_csv("./maotai.csv",index_col="date",parse_dates=["date"])
data=df.drop(labels="Unnamed: 0",axis=1,inplace=True)
#获取每个月的第一天的数据
df_monthly = df.resample("M").first()
df_yearly = df.resample("A").last()[:-1] #去除最后一年
cost_money = 0
hold = 0 #每年持有的股票
for year in range(2010, 2020):
cost_money -= df_monthly.loc[str(year)]['open'].sum()*100
hold += len(df_monthly[str(year)]['open']) * 100
if year != 2019:
cost_money += df_yearly[str(year)]['open'][0] * hold
hold = 0 #每年持有的股票
cost_money += hold * price_last
print(hold)
Matplotlib
人口数据分分析
政治
城市的温度和距离海洋距离的关系
机器学习
基于预测
基于分类
案例
toshare模块
构造方法