序列(Series)可以理解成是Python中的列表、元组的高级版本。为什么说是高级版本呢?因为序列一维数组类似,具有更好的广播效应,既可以与一个标量进行运算,又可以进行元素级函数的计算。如下例子所示:
#列表无法与一个标量进行运算(虽然*不报错,但是它表示的是重复) ls1 =[1,4,5] ls1+10Traceback (most recent call last):
列表与常数10相加,报错,显示无法将列表与整形值连接,“+”运算在列表中是连接操作
import pandas as pd #将列表转换为序列 series1 = pd.Series(ls1) print(series1+10)0 11
将上面的列表转换成一个序列后,就可以正常的完成运算,这就是序列的广播能力。同样,列表也不能用于元素级的数学函数,对比如下:
#列表无法应用于元素级的数学函数 ls2 = [1,3,8] print(pow(ls2,2))Traceback (most recent call last):
#将列表转换成序列 series2 = pd.Series(ls2) print(pow(series2,2))0 1
除了上面介绍序列功能,再来说说其他序列常用的场景,如序列的索引、成员关系、排重、排序、计数、抽样、统计运算等
序列的索引:
由于序列是列表的扩张版,故序列也有一套类似于列表的索引方法,具体如下:
#位置索引 import numpy as np np.random.seed(1) s1 = pd.Series(np.random.randint(size=5,low=1,high=10)) print(s1,'\n') print(s1[0],'\n')#取第一个元素 print(s1[1:3],'\n')#取第2~3个元素 print(s1[::2],'\n')#依次取数,步长为20 6
用倒数的方式取元素,序列就显得不是很方便了,我们推荐使用非常棒的iat方法,该方法不管应用于序列还是数据框都非常优秀,主要体现在简介而高速
print(s1.iat[-3],'\n')#取倒数第三个元素 print(s1[-3:],'\n')#取出倒数第三个及之后的所有元素6
然而,实际工作中很少通过位置索引(下标)的方法获取到序列中的某些元素,例如1000个元素构造的序列,查出属于某个范围值总不能一个个去数吧?序列提供了另一种索引的方法--布尔索引。具体用法如下:
np.random.seed(23) s1 = pd.Series(np.random.randint(size=5,low=1,high=100)) print(s1) print(s1[s1>=70])#取出大于等于70的值 print(s1[s1>=40][s1<=50])#取出40~50之间的值0 84
一个向量的元素是否包含于另一个向量,Python中对于一个一维数组,in1d函数实现该功能;对于一个序列,isin方法可实现该功能。
arr1 = np.array([1,2,3,4]) arr2 = np.array([10,20,3,40]) print(np.in1d(arr1,arr2),'\n') s3 =pd.Series(['A','B','C','D']) s4 = pd.Series(['X','A','Y','D']) print(s3.isin(s4)) print(np.in1d(s3,s4),'\n')[False False True False]
numpy模块中的in1d函数也可以用于序列的成员关系的比较
如果手中有一离散变量的序列,想查看该序列都有哪些水平,以及各个水平的频次,该如何操作?
#序列去重和水平统计 np.random.seed(10) s= np.random.randint(size=1000,low=1,high=4) #排重 print(pd.unique(s),'\n') #水平统计 print(pd.value_counts(s))[2 1 3]
借助于unique函数实现序列的排重,获得不同的水平值;通过使用value_counts函数对各个水平进行计数,并按频次降序呈现
有的时候需要对某个序列进行升序或降序排序,虽然这样的场景并不多,但排序在数据框中的应用还是非常常用的,先来看看如何对序列进行排序:
#序列的排序(排序函数默认升序) np.random.seed(1) s= pd.Series(np.random.normal(size=4)) #按序列的索引排序 print(s.sort_index(ascending=False),'\n')#按索引降序排列 #按序列的值排序 print(s.sort_values())#按序列的实际值升序排列3 -1.072969
dtype: float64
s =pd.Series([1, 20,20, 4,100,86,66]) result =s.value_counts()#对序列进行统计 print(result)#统计后的结果 value =result.index[0] print('频率最大的值:',value) count =result.iloc[0] print('最大的计数值',count)20 2
抽样也是数据分析中常用的方法,通过从总体中抽取出一定量的样本来推断总体水平;或者通过抽样将数据拆分成两部分,一部分建模,一部分测试。pandas模块提供了sample函数帮我们完成抽样的任务。
s.sample(n=None, frac=None, replace=False, weights=None, random_state=None, axis=None)
n:指定抽取的样本量;
frac:指定抽取的样本比例;
replace:是否有放回抽样,默认无放回;
weights:指定样本抽中的概率,默认等概论抽样;
random_state:指定抽样的随机种子;
#从1...100中随机抽取3个幸运儿 s = pd.Series(range(1,101)) print(s.sample(n=3,random_state=2),'\n') #从1...5中随机抽取3个幸运儿 s= pd.Series(range(1,6)) print(s.sample(n=3,replace=True,random_state=2),'\n')83 84
s = pd.Series(['男','女']) data =s.sample(n=10,replace=True,weights=[0.2,0.8],random_state=3) print(data)1 女
由于总体就是男、女性别两个值,故需要抽出10个样本,必须有放回的抽,而且男女被抽中的概率还不一致,女被抽中的概率是0.8。
统计运算
pandas模块提供了比numpy模块更丰富的统计运算函数,而且还提供了类似于R语言中的summary汇总函数,即describe函数。
#序列汇总 np.random.seed(1234) s =pd.Series(np.random.randint(size=100,low=10,high=30)) detail =s.describe() print(detail)count 100.000000
其中count是序列中非缺失元素的个数。如何判断一个序列元素是否为缺失呢?可以使用isnull函数。
#缺失值的判定 s= pd.Series([1,2,np.nan,4,np.nan,6]) print(s,'\n') print(s.isnull())0 1.0
除此,我们再来罗列一些常用的统计函数:
s.min() # 最小值
s.quantile(q=[0,0.25,0.5,0.75,1]) # 分位数函数
s.median() # 中位数
s.mode() # 众数
s.mean() # 平均值
s.mad() # 平均绝对误差
s.max # 最大值
s.sum() # 和
s.std() # 标准差
s.var() # 方差
s.skew() # 偏度
s.kurtosis() # 峰度
s.cumsum() # 和的累计,返回序列
s.cumprod() # 乘积的累积,返回序列
s.product() # 序列元素乘积
s.diff() # 序列差异(微分),返回序列
s.abs() # 绝对值,返回序列
s.pct_change() # 百分比变化 ,返回序列
s.corr(s2) # 相关系数
s.ptp() # 极差 R中的range函数