对于大多的数据分析应用,本书作者主要关注的内容为:
·在数据处理、清洗、构造子集、过滤、变换以及其他计算中进行快速的向量化计算。
·常见的数组算法,如sort、unique以及set操作等。
·高效的描述性统计和聚合/概述数据。
·数据排列和相关数据操作,例如对异构数据进行merge和join。
·使用数组表达式来表明条件逻辑,代替if-elif-else条件分支的循环。
·分组数据的操作(聚合、变换以及函数式操作)。
Numpy重要的原因:
·它的设计对于含有大量数组的数据非常有效。
·Numpy在内部将数据存储在连续的内存块中,这与其他的Python内建数据结构是不同的。Numpy的算法库是用C语言编写的,所以在操作数据内存时,不需要任何类型检查或者其他管理操作。Numpy数组使用的内存量也小于其他Python内建序列。
·Numpy可以针对全量数组进行复杂计算而不需要写Python循环。
4.1 Numpy ndarray:多维数组对象
Numpy的核心特征之一就是N维数组对象-ndarray。ndarray是Python中的一个快速、灵活的大型数据集容器。数组允许使用类似于标量的操作语法在整块数据上进行数学计算。
一个ndarray是一个通用的多维同类数据(包含的每一个元素均为相同类型)容器。,每一个树组都有一个shape属性(用来表征每一维度的数量),每一个数组都有一个dtype属性(用来描述数组的数据类型)。
ndarray(数组、Numpy数组、ndarray对象)
使用array函数生成数组。array函数接收任意的序列型对象,生成一个新的包含传递数据的Numpy数组。例如:
嵌套序列,例如同等长度的列表,会自动转换为多维数组:
给定长度及形状后,使用zeros创建全0数组。使用ones创建全1数组。empty可以创建一个没有初始化数值的数组。若创建高维数组,则需要为shape传递一个元祖:
下表展示标准数组的生成函数。Numpy专注于数值计算,如果没有特别指明,则默认的数据类型是float64(浮点型):
数据类型,即dtype(Numpy能够与其他系统数据灵活交换的原因),是一个特殊的对象,包含了ndarray需要为某一种类型数据所申明的内存块信息(也称为元数据,即表示数据的数据):
Numpy数据类型:
使用astype方法显式地转换数组的数据类型:将浮点数转换为整数的时候,不会进行四舍五入的操作,会直接舍弃小数点之后的数字。注意数据类型需要加上 “np.”
使用astype时总是生成一个新的数组。
任何在两个 等尺寸数组之间的算术操作都是逐元素操作的形式:
带有标量的算术操作,会把计算参数传递给数组的每一个元素:
同尺寸的数组进行比较,会产生一个布尔值数组:
Numpy数值索引与Python列表看起来类似,如果传入了一个数值给数组,数值被传递了整个切片,区别于Python的内建列表, 数组的切片是原数组的视图。意味着数组并不是被复制了, 任何对于视图的修改都会反映到原数组中:
不写切片值的[:]将会引用数组的所有值:
拷贝数组切片而不是一份视图,就必须显式的复制这个数组:
对于高维数组,每个索引值对应的元素是一个数组:
在多维数组中,可以省略后序索引值,返回的对象将是降低一个维度的数组,例如在一个223(理解为2个2*3的数组)的数组中:
标量和数组都可以传递给arr3d:
类似的arr3d[1,0]或者arr3d[1][0]返回的是一个一维数组:
注意:上述的数组子集选择中,返回的数组都是视图。
数组的切片索引:
布尔值数组的长度必须和数组轴索引长度一致。
当布尔值数组的长度不正确时,布尔值选择数据的方法并不会报错,注意使用。
可以使用!=或者在条件前边使用~对条件取反:~符号可以对通用条件进行取反
当需要选择三个名字中的两个时,可以对多个布尔值条件进行联合使用操作符&->and和|->or:
使用布尔值索引进行选择数据时,总是生成数据的拷贝,即使返回的数组并没有任何变化。
神奇索引是Numpy中的术语,用于描述使用整数数组进行数据索引。
传递多个索引数组情况,会根据每个索引元祖对应的元素选出一个一维数组:
注意:神奇索引与切片不同,神奇索引总是将数据复制到一个新的数组中 。
转置是一种特殊的数据重组方式,可以返回底层数据的视图而不需要复制任何内容。
数组有transpose方法和特殊的T属性:
对于更高维度的数组,transpose方法可以接收包含轴编号的元祖,用于置换轴:下图所示,对第一个轴和第二个轴进行置换:
解释:这里的轴转换为(x,y,z)->(y,x,z)
例如:数组中的4和8交换位置,就是(0,1,0)->(1,0,0)
ndarray有一个swapaxes方法交换轴,该方法接收一对轴编号作为参数,并对轴调整进行重组数据:
注意:wapaxes方法返回的是数据的视图,而没有对数据进行复制。
4.2 通用函数:快速的逐元素数组函数
通用也可以称为ufunc,是一种在ndarray数据中进行逐元素操作的函数。
一元通用函数,例如:
二元通用函数,会接收两个数组并返回一个数组作为结果:
也有一些通用函数返回多个数组,如modf:返回一个浮点值数组的小数部分和整数部分:
一元通用函数:
二元通用函数:
4.3 使用数组进行面向数组编程
什么叫向量化?(使用Numpy数组使我们能够利用简单的数组表达式完成多种数据操作任务,而无需编写大量循环,利用数组表达式来代替显式循环的方法叫做向量化)
numpy.where函数是三元表达式x if condition else y 的向量化版本:
如果cond条件满足,返回xarr的结果,否则返回yarr的结果
np.where的第二个和第三个参数并不需要是数组,也可以是标量。当需求为把一个矩阵的正值都替换为2,负值都替换为-2,使用它可以很容易实现:
也可以使用其将标量和数组联合,例如,将arr中的所有正值替换为2:
基础数组统计方法:
实例:
cumsum和cumprod并不会聚合,它们会产生一个中间结果,但可以指定轴向上根据较低维度的切片进行部分聚合:
布尔值会被强制为1(True)、0(False)。
sum通常可以用来计算布尔值数组的中True个数:
any检查数组中是否至少有一个True,all检查是否每个值都是True:
这些方法也可以适用于非布尔值数组。所有的非0元素都会被当做True处理。
Numpy包含一些针对一维ndarray的基础集合操作。
np.unique()方法返回的是数组中唯一值排序后形成的数组:
np.in1d(arr1,arr2)检查数组arr1中的值是否在arr2中:
Numpy中集合函数如下:
4.4 使用数组进行文件输入和输出
Numpy可以在硬盘中将数据以文本或二进制文件的形式进行存入硬盘或由硬盘载入。
4.5 线性代数
numpy.linalg拥有一个矩阵分解的标准函数集:
实例:
4.6 伪随机数生成
numpy.random模块填补了Python内建的random模块的不足,可以高效地生成多种概率分布下的完整样本值数组。
numpy.random.normal(loc=0.0, scale=1.0, size=None)
loc:float
此概率分布的均值(对应着整个分布的中心centre)
scale:float
此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
size:int or tuple of ints
输出的shape,默认为None,只输出一个值
称这些为伪随机数。因为它们是由具有确定性行为的算法根据随机数生成器中的随机数种子生成的。可以使用np.random.seed更改随机数种子:
np.random.seed(1234)
numpy.random中的数据生成函数公用了一个全局的随机数种子。为了避免全局状态,可以使用numpy.random.RandomState生成一个随机数生成器,使数据独立于其他随机数状态:
numpy.random中部分函数:
4.7 示例:随机漫步
使用python内建random模块利用纯python实现一个1000步的随机漫步:
import random
import matplotlib.pyplot as plt
position = 0
walk = [position]
steps = 1000
for i in range(steps):
step = 1 if random.randint(0,1) else -1
position += step
walk.append(position)
plt.plot(walk[:100])
plt.show
可视化:
只能观察到对随机步进的累积,并且可以通过一个数组表达式实现。
使用np.random模块一次性抽取1000次投掷硬币的结果,每次投掷的结果为1或者-1,然后计算累计值:
import numpy as np
nsteps = 1000
#随机生成一个一维数组数值为0或者1,一维数组大小为1000
draws = np.random.randint(0,2,size = nsteps)
#将大于0的变为1,小于0的变为-1
steps = np.where(draws>0,1,-1)
#求每一个硬币当前的累积和
walk = steps.cumsum()
#最大最小值
walk.min(),walk.max()
#求第一次连续向某个方向走10步的位置
(np.abs(walk)>=10).argmax()
#目标是模拟多次随机漫步,比如说5,000步。
#可以稍微地修改下之前的代码来生成所有的随机步。
#如果传入一个2个元素的元组,numpy.random中的函数可以生成一个二维的抽取数组
#并且可以一次性地跨行算出全部5,000个随机步的累积和:
nwalks = 5000
nsteps = 1000
draws = np.random.randint(0,2,size=(nwalks,nsteps))
steps = np.where(draws>0,1,-1)
walks = steps.cumsum(1)
walks
#现在可以计算出这些随机步的最大值和最小值:
walks.min(),walks.max()
#在这些随机步中计算出30或-30的最小穿越时间。
#这有点棘手,因为不是所有的5,000个都达到了30。
#可以用any方法来检查:
hits30 = (np.abs(walks)>=30).any(1)
hits30
hits30.sum()
#可以使用布尔值数组来选出绝对步数超过30的步所在的行
#并使用argmax从轴向1上获取穿越时间
crossing_times = (np.abs(walks[hits30])>=30).argmax(1)
crossing_times.mean()
5.1 pandas数据结构介绍
Series和DataFrame
Series是一种一维的数组型对象,包含了一个值序列,并且包含了数据标签,称为索引(index)。交互模式环境中Series的字符串表示索引在左边,值在右边。最简单的序列可以仅仅由一个数组形成:
通过values属性和index属性分别获得Series对象的值和索引:
修改索引值,通常需要创建一个索引序列(也就是index参数用一个数组接收),用标签标识每个数据点:
可以通过index来进行索引:
使用numpy中的函数或者其风格的操作。例如使用布尔值数组进行过滤,与标量相乘,或是应用数学函数,这些操作将保存索引连接:
Series将索引与值按照位置进行对应,可以认为它是一个长度固定且有序的字典:
可以使用字典生成一个Series对象:
可以在传入字典的时候按照自己想要的索引顺序传递给index参数:
上边因为原来的字典索引中没有索引’A’,所以它对应的值就是空值,用NaN表示。
pandas中使用isnull和notnull函数来检查缺失数据:
Series对象自身和其索引都具有name属性:
Series的索引可以通过位置赋值的方式进行改变:
DataFrame表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值、字符串、布尔值等)。 DataFrame既有行索引,也有列索引,可以被视为一个共享相同索引的Series的字典。在DataFrame中,数据被存储为一个二维以上的块,而不是列表、字典或其他一维数组的集合。
最常用构建DataFrame方式是利用等长度列表或者numpy数组的字典来形成DataFrame:
如果指定了列的顺序。则会按照指定顺序排列:
如果传的列不包含在字典中,则在结果中会出现缺失值:
DataFrame中的一列,可以按字典型标记或属性那样检索为Series:
列的引用是可以修改的,列可以赋值为标量值或值数组:
将列表或数组赋值给一个列时,值的长度必须和DataFrame的长度相匹配。如果你将Series赋值给一列时,Series的索引将会按照DataFrame的索引重新排列,并在空缺的地方填充缺失值:
如果被赋值的列并不存在,则会生成一个新的列。del关键字可以像在字典中那样对DataFrame删除列。
在del的例子中,首先增加一列,这一列是布尔值,判断条件是state列是否为’ohio’:
使用包含字典的嵌套字典,外边字典的键代表列索引columns,内部字典的键代表行索引index:
对DataFrame进行转置操作(调换行和列):
内部字典的键被联合、排序后形成了结果的索引。如果已经显式指明索引的话,内部字典的键将不会被排序。
包含Series的字典也可以用于构造DataFrame:
如果DataFrame的索引和列拥有name属性,则这些name属性也会被显示:
和Series类似,DataFrame的values属性会将包含在DataFrame中的数据以二维ndarray的形式返回:
如果DataFrame的列是不同的dtypes,则values的dtype会自动选择适合所有列的类型:
DataFrame构造函数的有效输入:
pandas中的索引对象是用于存储轴标签和其他元数据的(例如轴名称或标签)。在构造Series或DataFrame时,所使用的任意数组或标签序列都可以在内部转换为索引对象:
索引对象是不可变的,因此用户是无法修改索引对象的:
不变性使得在多种数据结构中分享索引对象更为安全:
除了类似数组,索引对象也像一个固定大小的集合:
与Python集合不同,pandas索引对象可以包含重复标签:
每个索引都有一些集合逻辑的方法和属性,这些方法和属性解决了关于它所包含的数据的其他常见问题。一些 索引对象的方法和属性:
5.2 基本功能
了解与Series或DataFrame中数据交互的基础机制。
reindex是pandas对象的重要方法,该方法用于创建一个符合新索引的新对象。
Series调用reindex方法 (注意是Series对象)时,会将数据按照新的索引进行排列,如果某个索引值之前并不存在,则会引入缺失值:
对于顺序数据,比如时间序列,在重建索引时可能会需要进行插值或填值。method可选参数允许我们使用诸如ffill等方法在重建索引时插值, ffill方法会将值前向填充(比如这里0有值,填充时1没有值,所以0位置的值前向填充到1位置,即1位置也是purple):
在 DataFrame中,reindex可以改变行索引、列索引,也可以同时改变二者。当仅传入一个序列时,结果中的行会重建索引(只传入一个序列时,改变的是行索引index):
列可以使用columns关键字重建索引:
可以使用loc进行更为简洁的标签索引:
可以看到有提示,让使用.reindex()
如果已经拥有索引数组或不含条目的列表,在轴向上删除一个或更多的条目,drop方法会返回一个含有指示值或轴向上删除值的新对象:
在DataFrame中,索引值可以从轴向上删除。
很多函数,例如drop,会修改Series或DataFrame的尺寸或形状,这些方法直接操作原对象而不返回新对象: 设置inplace参数为True
Series的索引(obj[…])与NumPy数组索引的功能类似,只不过Series的索引值可以不仅仅是整数:
普通的Python切片中是不包含尾部的,Series的切片与之不同:
使用这些方法设值时会修改Series相应的部分:
使用单个值或序列,可以从DataFrame中索引出一个或多个列(不能直接索引行名称):
行选择语法data[:2]非常方便。传递单个元素或一个列表到[]符号中可以选择列。
可以根据一个布尔值数组切片或选择数据:
使用布尔值DataFrame进行索引,布尔值DataFrame可以是对标量值进行比较产生的:
使用loc和iloc选择数据:
针对DataFrame在行上的标签索引,使用特殊的索引符号loc和iloc。
通过标签选出单行多列的数据作为基础示例:
使用整数标签iloc进行类似的数据选择:
除了单个标签或标签列表之外,索引功能还可以用于切片:
为了保持一致性,如果你有一个包含整数的轴索引,数据选择时请始终使用标签索引。
为了更精确地处理,可以使用loc(用于标签)或iloc(用于整数):
不同索引的对象之间的算术行为是pandas提供给一些应用的一项重要特性。将对象相加时,如果存在某个索引对不相同,则返回结果的索引将是索引对的并集:
没有交叠的标签位置上,内部数据对齐会产生缺失值。缺失值会在后续的算术操作上产生影响。
在DataFrame的示例中,行和列上都会执行对齐:
将这些对象加在一起,返回一个DataFrame,它的索引、列是每个DataFrame的索引、列的并集:
如果将两个行或列完全不同的DataFrame对象相加,结果将全部为空。
使用填充值的算术方法
在两个不同的索引化对象之间进行算术操作时,可能会想要使用特殊填充值,比如当轴标签在一个对象中存在,在另一个对象中不存在时,将缺失值填充为0:
Series和DataFrame的算术方法:
这些方法中的每一个都有一个以r开头的副本,这些副本方法的 参数是翻转的。因此下面两个语句的结果是等价的:
与此相关的一点,当对Series或DataFrame重建索引时,也可以指定一个不同的填充值:
DataFrame和Series间的操作:
先创建DataFrame和Series对象:
默认情况下,DataFrame和Series的数学操作中会将Series的索引和DataFrame的列进行匹配,并广播到各行:
如果一个索引值不在DataFrame的列中,也不在Series的索引中,则对象会重建索引并形成联合:
如果想改为在列上进行广播,在行上匹配,必须使用算术方法中的一种。例如:
NumPy的通用函数(逐元素数组方法)对pandas对象也有效:
另一个常用的操作是将函数应用到一行或一列的一维数组上。DataFrame的apply方法可以实现这个功能:
据frame中的每个浮点数计算一个格式化字符串,可以使用applymap方法:
使用applymap作为函数名是因为Series有map方法,可以将一个逐元素的函数应用到Series上:
需按行或列索引进行字典型排序,需要使用sort_index方法,该方法返回一个新的、排序好的对象
在DataFrame中,可以在各个轴上按索引排序:
数据默认会升序排序,但是也可以按照降序排序:
如果要根据Series的值进行排序,使用sort_values方法:
默认情况下,所有的缺失值都会被排序至Series的尾部:
当对DataFrame排序时,可以使用一列或多列作为排序键。为了实现这个功能,传递一个或多个列名给sort_values的可选参数by:
对多列排序时,传递列名的列表:
排名是指对数组从1到有效数据点总数分配名次的操作。
Series和DataFrame的rank方法是实现排名的方法,默认情况下,rank通过将平均排名分配到每个组来打破平级关系:
可用的平级关系打破方法列表:
DataFrame可以对行或列计算排名:
带有重复索引的情况下,数据选择是与之前操作有差别的。根据一个标签索引多个条目会返回一个序列,而单个条目会返回标量值:
相同的逻辑可以拓展到在DataFrame中进行行索引:
5.3 描述性统计的概述与计算
考虑一个小型的DataFrame:
调用DataFrame的sum方法返回一个包含列上加和的Series:
除非整个切片上(在本例中是行或列)都是NA,否则NA值是被自动排除的。可以通过禁用skipna来实现不排除NA值:
归约方法sum的可选参数:
idxmin和idxmax,返回的是间接统计信息,比如最小值或最大值的索引值:
除了归约方法外,有的方法是积累型方法:
还有一类方法既不是归约型方法也不是积累型方法。describe就是其中之一,它一次性产生多个汇总统计:
对于非数值型数据,describe产生另一种汇总统计:
汇总统计相关方法:
Series的corr方法计算的是两个Series中重叠的、非NA的、按索引对齐的值的相关性。相应地,cov计算的是协方差。
另一方面,DataFrame的corr和cov方法会分别以DataFrame的形式返回相关性和协方差矩阵。
函数unique,它会给出Series中的唯一值:
唯一值并不一定按照排序好的顺序返回,但是如果需要的话可以进行排序(uniques.sort())。相应地,value_counts计算Series包含的值的个数:
value_counts也是有效的pandas顶层方法,可以用于任意数组或序列:
isin执行向量化的成员属性检查,还可以将数据集以Series或DataFrame一列的形式过滤为数据集的值子集:
与isin相关的Index.get_indexer方法,可以提供一个索引数组,这个索引数组可以将可能非唯一值数组转换为另一个唯一值数组:
方法统计:
参考:《利用Python实现数据分析》
Original: https://blog.csdn.net/qq_42433311/article/details/123324131
Author: QYiRen
Title: Numpy、pandas基础(数据分析)
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/759646/
转载文章受原作者版权保护。转载请注明原作者出处!