一文带你斩杀Python之Numpy Pandas全部操作
Numpy简介
Numpy专门针对ndarray的操作和运算进行了设计,所以数组的存储效率和输入输出性能远优于Python中的嵌套列表,数组越大,Numpy的优势就越明显。Numpy系统是Python的一种开源的数值计算扩展。这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表(nested list structure)结构要高效的多(该结构也可以用来表示矩阵(matrix))。据说NumPy将Python相当于变成一种免费的更强大的MATLAB系统。
ndarray中的所有元素的类型都是相同的,而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python原生lis就t只能通过寻址方式找到下一个元素,这虽然也导致了在通用性能方面Numpy的ndarray不及Python原生list,但在科学计算中,Numpy的ndarray就可以省掉很多循环语句,代码使用方面比Python原生list简单的多。
总的来说,在科学计算和大数据的处理上面,numpy的优势远远超过了原生态的Python内置方法,正所谓“工欲善其事必先利其器”,任何一门工程学科的发现和精进,都离不开各种软件的升级和迭代。
Numpy操作集合
1、不同维度数据的表示
1.1 一维数据的表示
# 列表
[1,2,'a',4]
在Python中,最为常见的数据类型就是列表,列表是一维的数据,同时也是我们处理数据的常见集装箱。

在anaconda里面的jupyter notebook里面,我们直接使用pip安装这一个库,一般的anaconda会自带numpy这一个第三方库。
在使用numpy的时候,首先要引入这一个第三方库,使用:import numpy as np即可,便于为我们后面的方法属性调用。
在构造最为基本的numpy数据时,我们使用numpy的array()方法,里面就是一个列表形式的,可以是多维数组,最终构造成:ndarray类型


# 集合
set([1,'a',3,4]) #集合的元素唯一且无序
# 元组
tuple([1,'a',3,4])#元组的元素不可变
对于Python里面的常见的几种数据类型:字符串、元组、列表、字典、集合,重点需要注意的是字符串和元组是不可修改的,但是可以通过索引来组合和切断这些元素,例如:

** 我们发现,元组是不可以修改的,但是我们的列表却可以**

那么就会有小伙伴疑问了,那么不可修改,怎么办!我们可以通过下面的方法:
直接在同一个元组上更新是不可行的,但是可以通过拷贝现有的元组片段构造一个新的元组的方式解决。
通过分片的方法让元组拆分成两部分,然后再使用连接操作符(+)合并成一个新元组,最后将原来的变量名(temp)指向连接好的新元组。在这里就要注意了,逗号是必须的,小括号也是必须的!
temp = ('小鸡','小狗','小猪')
temp = temp[:2] + ('小猴子',) + temp[2:]
print(temp)
('小鸡', '小狗', '小猴子', '小猪')
删除元组中的元素:对于元组是不可变的原则来说,单独删除一个元素是不可能的,当然你可以利用切片的方式更新元组,间接的删除一个元素。
temp = ('小鸡','小狗','小猪')
temp = temp[:1] + temp[2:]
print(temp)
('小鸡', '小猪')
在日常中很少用del去删除整个元组,因为Python的回收机制会在这个元组不再被使用的时候自动删除。如果整个删除那么就会报错!!!
1.2 二维数据的表示

最简单的方法就是使用列表进行二维数组的创建,那么如果我们不使用这种方法,我们应该如何去做呢?

答案是:numpy的array()
我们也可以将一个numpy装换为dataframe类型,也就是我们的二维数据表


我们使用Python里面的最强大的pandas库,进行处理,构造一个二维数组,使用pandas里面的column方法,对数组的标签进行自定义。
1.3 三维数据的表示

如何去理解这个维度呢?首先我们知道任何一个数组都是需要一个[]进行包裹的,其实最为简单的判断方法就是看[]的个数,从左到右,数一下,三个,那么就是三维数组,简单粗暴但是言简意赅。

其实从数据表里面我们可以看出,如果需要组成这样二维单独的数据表,那么就是二维数据,在单元的数据表中,仍然存在数组的嵌套,那么就是维度的+1
2、 为什么要使用Numpy
2.1、Numpy的ndarray具有广播功能
查看版本

** np.array?**
可以查看官方的解释,同时我们也可以使用np.info(np.array)对方法进行查看和学习
有时候我们需要产生一个特定范围的的数组,而且我们希望数据是平均的分配,这个时候我们我们就可以使用numpy的linspace()方法了,它的功能就是产生一个特定平均份数的一维数组。
np.linspace(start,end,count):注意它会将开始元素和末尾的元素都取到,然后按照count份数进行分割
np.empty(行,列):也就是产生特定的维度,多少行和列的数组

q = np.array([1,2,3,4],dtype=np.complex128)
print("数据类型",type(q)) #打印数组数据类型
print("数组元素数据类型:",q.dtype) #打印数组元素数据类型
print("数组元素总数:",q.size) #打印数组尺寸,即数组元素总数
print("数组形状:",q.shape) #打印数组形状
print("数组的维度数目",q.ndim) #打印数组的维度数目
初学者总是把这些属性记成了方法,注意我们的属性是没有()的
2.2 Numpy数组的性能比Python原生数据类型高

通过这个例子,我们可以看到numpy的效率远远高于我们的list列表原生态的执行速度和效率
3 ndarray的属性和基本操作
3.1 ndarray的基本属性

3.2 ndarray元素类型
那么有时候我们再想,如果数组的长度不一致,那么会不会有影响呢?
通过例子,我们发现,如果构造的数据长度不一致,不会报错,但是会发出警告,也就是说这种方法,在Python里面还是支持的,但是我们发现它被单独的构造为一个list类型了,元素大小也就发生了改变,将一个列表嵌套在一个列表当中。
我们可以看看长度一致的情况:

** 显然是符合我们的要求的**
3.3 创建ndarray的方式

创建的时候可以指定我们的数据类型

np.arange(),返回的是序列数组,最后一个取不到,一维的
np.ones(3,4),返回的是3行4列的全1数组,如果里面有三个数字,那么第一数字代表里面,有多少个单独独立的数组
np.zeros(数组,行,列)生成一个多少个独立数组,每个独立数组里面有多少行,多少列,最后类型是全0数组,如下:

np.full((n,m),value),生成一个特定维度的数组,且元素由自己定义
np.eye(n),生成一个nxn的单位矩阵

np.ones_like(array),生成一个和目标数组一样的全1数组

使用np.linspace(),形成新的一维序列数组
使用np.concatenate((array1,array2),axis=0):按照行进行拼接
** np.concatenate((array1,array2),axis=1):按照列进行拼接**

如果这里使用横向连接,那么就会报错,为了防止报错,我们可以使用装置功能

拼接也要注意,是否可以!!!
3.4 ndarray对象的变换

我们可以根据自己需要变换我们的一维数组,为多维数组,使用reshape(行,列)

这个方法也可以修改,但是要注意的是:resize(方法)修改的是原数组,而reshape(方法)并没有修改原数组,需要赋值给新的变量,该修改才能生效。
使用swapaxes(1,0)进行维度调换,原来的行数变成现在的列数,**不改变原数组
**

** flatten()降维处理,一维,不改变原数组**

** astype(np.int16),或者其他的numpy数据类型,直接拷贝数据类型格式**

转换为list类型
3.5 ndarray对象的操作

索引和我们Python里面的较为相似,如果里面存在多个独立数组,那么第一个索引只取出大的数组框,然后后面对应的就是行和列

对于步长而言,我们要明确的是,索引从0开始,最后一个索引永远取不到,其次,不写出的索引为默认取到,对于步长取索引,我们按照空格方法记忆最好!
4 、Numpy的函数与数组运算
4.1 数组与标量之间的运算


4.2 对数组的元素进行运算

4.3 数组之间的运算

4.4 统计函数

np.sum(array,axis=(0,1))对行和列进行求和,那么就是所有元素相加,如果是1,那么就是行,0就是列
有小伙伴对axis=1,0的具体含义有很多的疑问:这里给出解释:
注意看,官方对于0和1的解释是轴,也就是坐标轴。而坐标轴是有方向的,所以千万不要用行和列的思维去想axis,因为行和列是没有方向的,这样想会在遇到不同的例子时感到困惑。
根据官方的说法,1表示横轴,方向从左到右;0表示纵轴,方向从上到下。当axis=1时,数组的变化是横向的,而体现出来的是列的增加或者减少。
其实axis的重点在于方向,而不是行和列。具体到各种用法而言也是如此。当axis=1时,如果是求平均,那么是从左到右横向求平均;如果是拼接,那么也是左右横向拼接;如果是drop,那么也是横向发生变化,体现为列的减少。
当考虑了方向,即axis=1为横向,axis=0为纵向,而不是行和列,那么所有的例子就都统一了。

对于这些方法,熟悉和掌握是两回事,熟能生巧.......
4.5 随机函数

仔细观察这两个方法:
np.random.rand()是产生0,1的分布随机数
np.random.randn()产生的是标准正态分布随机数
有n的是正态分布随机数,没有的是0,1的随机数

** 随机种子**

数组打乱

5 、Numpy数据的存取
5.1 csv数据文件的存取

一般在numpy里面对于数据保存和载入,没有经常性的要求,因为在pandas里面提供了大量的方法,为我们载入和保存。
Pandas简介
Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。
Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。
Time- Series:以时间为索引的Series。
DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。
Panel :三维的数组,可以理解为DataFrame的容器。
Pandas 有两种自己独有的基本数据结构。读者应该注意的是,它固然有着两种数据结构,因为它依然是 Python 的一个库,所以,Python 中有的数据类型在这里依然适用,也同样还可以使用类自己定义数据类型。只不过,Pandas 里面又定义了两种数据类型:Series 和 DataFrame,它们让数据操作更简单了。
Pandas操作集合
1 、pandas数据结构之Series
1.1 创建Series
# 导入pandas和numpy
!pip install numpy
!pip install pandas
import pandas as pd
import numpy as np
1.1.1 从ndarray创建Series

pd.Series():创建一个数据表,里面的index提供了索引的方法,给出的是一个列表的类型。
同时也可以使用index取出标签索引
1.1.2 从字典或列表创建Series

Series提供了字典的类型,进行组合,就算是我们有缺失的键值对,但是我们可以自己定义标签index

列表也可以完成,这在我们进行爬虫的时候,我们可以用列表容器进行,存储
1.1.3 从标量创建

创建的是一样的值,我们可以根据自己的需要进行
1.2 对Series的操作
1.2.1 Series和ndarray相似的操作

按照索引进行取值和修改

** get()方法,如果存在这样的键值对,那么就可以取出来,但是如果不存在,就会使用后面的那个默认值**

索引切片和我们之前介绍的Python内置方法也是一样,和numpy里面的思想也差不多,这里就不多多赘述了。

1.2.2 向量化运算

1.2.3 类似字典的操作

我们发现列表解析原来如此的强大,为我们减轻很多的麻烦,其实如果你熟练掌握Python的基础语法,这一点你也是可以理解的

1.2.4 时间序列操作
pd.date_range():
pd.date_range(
start=None,#开始时间
end=None,#截止时间
periods=None,#总长度
freq=None,#时间间隔
tz=None,#时区
normalize=False,#是否标准化到midnight
name=None,#date名称
closed=None,#首尾是否在内
**kwargs,
)

asfreq("时间频率"):改变时间频率

索引思想依然一致

按照步长进行索引的搜寻

2、pandas数据结构之DataFrame
2.1 DataFrame的创建
2.1.1 从Series or dicts创建

通过字典进行构造,这也满足了,我们如何把字典类型转换为dataframe类型,最后保存在我们需要的数据表类型里面

说实话,在我们的日常数据处理里面,我们一般是把字典嵌套在列表里面,那么我们就可以把列表放入这个里面,最后转换为dataframe类型存储

2.1.2 从ndarrays或lists的字典创建

不加index,默认数字序列


** 行标签,column如果和字典的键不对应,那么就会为空,这个是需要注意的**

2.1.3 从结构化或成对的array/list创建

三维数组进行,数据表展示,就是这样的

2.1.3 从字典的列表创建

2.2 变量选择、添加和删除
这里交代了数据表里面一般拼接,增加和赋值操作

df['字段']=pd.Series([填充字段],index=[列标签]),可以达到对数据表的增加,在特定的列索引上面添加数据


删除并显示值,该列数据
对某一列删除操作
**会根据索引来进行匹配,没有匹配到索引的,将会填充为NaN **

3、 数据导出
为了演示数据的导出。这里我们引入一个新的第三方库tushare,通过这个库,我们可以轻松的获取金融相关数据,如股票数据。
以下为tushare库的介绍。其官方文档地址为:TuShare是一个免费、开源的python财经数据接口包。主要实现对股票等金融数据从数据采集、清洗加工 到 数据存储的过程,能够为金融分析人员提供快速、整洁、和多样的便于分析的数据,为他们在数据获取方面极大地减轻工作量,使他们更加专注于策略和模型的研究与实现上。
考虑到Python pandas包在金融量化分析中体现出的优势,TuShare返回的绝大部数据格式都是pandas DataFrame类型,非常便于用pandas/NumPy/Matplotlib进行数据分析和可视化。
当然,如果您习惯了用Excel或者关系型数据库做分析,您也可以通过TuShare的数据存储功能,将数据全部保存到本地后进行分析。
我们先获取2017年,第二季度全部股票的业绩报告,盈利能力,营运能力数据,然后分别用不同方式保存它们。
!pip install wheel
!pip install lxml
!pip install tushare
!pip install beautifulsoup4
!pip install requests
!pip install pandas
import tushare as ts
# 业绩报告
report = ts.get_report_data(2017,2)
# 盈利能力
profit = ts.get_profit_data(2017,2)
# 营运能力
operation = ts.get_operation_data(2017,2)

3.1 导出到本地文件
3.1.1 导出为文本文件
report.to_csv('./report.csv',index = False,encoding = 'utf-8')
profit.to_csv('./profit.csv',index = False,encoding = 'utf-8')
operation.to_csv('./operation.csv',index = False,encoding = 'utf-8')
3.1.2 导出为Excel文件
# 可以分别导出到不同的Excel工作簿;
!pip install openpyxl
report.to_excel('./report.xlsx',index =False)
profit.to_excel('./profit.xlsx',index = False)
operation.to_excel('./operation.xlsx',index =False)
在pandas里面提供了大量的数据载入和数据导出的方法
#先打开一个Excel工作簿,然后分别写入三个表格,然后关掉Excel工作簿
writer = pd.ExcelWriter('./finance.xlsx')
report.to_excel(writer,sheet_name='report',index = False)
profit.to_excel(writer,sheet_name='profit',index = False)
operation.to_excel(writer,sheet_name='operation',index = False)
# 文件写入完毕后关掉Excel工作簿
writer.close()
3.1.3 导出为Json文件
# 导出为json文件
report.to_json('./report.json')
3.1.4 导出为hdf文件
# 导出为hdf文件
!pip install tables
from warnings import filterwarnings
filterwarnings('ignore')
report.to_hdf('./report.hdf','report')
# ImportError: HDFStore requires PyTables, "No module named 'tables'" problem importing
3.2 将数据存储到数据库
import sqlite3
# 创建连接
sqlite_con = sqlite3.connect('./pandas.db')
# 写入数据
report.to_sql('report',sqlite_con,if_exists ='replace',index =False)
profit.to_sql('profit',sqlite_con,if_exists ='replace',index =False)
operation.to_sql('operation',sqlite_con,if_exists ='replace',index =False)
3.3 数据导入
3.3.1 从本地文件
# 从文本文件
# 推荐使用相对路径
pd.read_csv('./report.csv').head(3)

#从Excel文件
# 如果不是被迫选择Excel文件格式,一般不推荐使用Excel文件格式,速度很慢
!pip install xlrd
pd.read_excel('./report.xlsx').head()


4 、分组计算与汇总
如果说,数据的导入和导出是数据的前提,那么数据的处理分析那么就是数据的精华

按照不同的字段进行分组聚合统计,count()计数,sum()求和



按照不同的字段分别分组聚合,然后进行统计分析,输出需要显示的指标变量的值
注意这里的describe()用于描述性分析,直接可以使用该方法
5、数据融合

构造两个临时数据表,用于我们后面的操作

直接进行连接


Pandas高级操作补充

对于pandas的高级操作,无非是进行数据增删改查,也就是分组聚合,排序处理等,在处理数也可以使用其他的工具,例如:MySQL数据库的分析,也还是不错的!!!