f.排序
Pandas有两种排序方式,它们分别是按标签与按实际值排序。
import numpy as np d = {'Name':pd.Series(['Tom','James','Ricky','Vin','Steve','Minsu','Jack','Lee','David','Gasper','Betina','Andres']), 'Age':pd.Series([25,26,25,23,30,29,23,34,40,30,51,46]), 'Rating':pd.Series([4.23,3.24,3.98,2.56,3.20,4.6,3.8,3.78,2.98,4.80,4.10,3.65])} unsorted_df = pd.DataFrame(d)
按标签(行)排序
使用sort_index()方法,通过传递axis参数和排序顺序,可以对DataFrame进行排序。 默认情况下,按照升序对行标签进行排序。
# 按照行标进行排序 sorted_df=unsorted_df.sort_index() print (sorted_df) # 控制排序顺序 sorted_df = unsorted_df.sort_index(ascending=False) print (sorted_df)
按标签(列)排序
# 按照列标签进行排序 sorted_df=unsorted_df.sort_index(axis=1) print (sorted_df)
按某列值排序
像索引排序一样,sort_values()是按值排序的方法。它接受一个by参数,它将使用要与其排序值的DataFrame的列名称。
sorted_df = unsorted_df.sort_values(by='Age') print (sorted_df) # 先按Age进行升序排序,然后按Rating降序排序 sorted_df = unsorted_df.sort_values(by=['Age', 'Rating'], ascending=[True, False]) print (sorted_df)
g.数据合并
concat
concat函数是pandas的方法,可以根据不同的轴合并数据集。
concat函数的基本语法如下:
pandas.concat(objs: Union[Iterable[‘DataFrame’], Mapping[Label, ‘DataFrame’]], axis='0', join: str = "'outer'", ignore_index: bool = 'False', keys='None', levels='None', names='None', verify_integrity: bool = 'False', sort: bool = 'False', copy: bool = 'True')
常用参数如下:
参数名称 | 说明 |
objs | 接收多个Series,DataFrame,Panel的组合。表示参与连接的pandas对象的列表的组合。无默认。 |
axis | {0/’index’, 1/’columns’}, default 0 |
join | 接收inner或outer。表示其他轴向上的索引是按交集(inner)还是并集(outer)进行合并。默认为 outer。 |
join_axes | 接收Index对象。表示用于其他n-1条轴的索引,不执行并集/交集运算。 |
s1 = pd.Series(['a', 'b']) s2 = pd.Series(['c', 'd']) pd.concat([s1, s2]) # 忽略存在的index,并且重新设定index值 pd.concat([s1, s2], ignore_index=True) # 增加复合索引 pd.concat([s1,s2],keys=['s1','s2']) # 合并两个DataFrame df1 = pd.DataFrame([['a', 1], ['b', 2]],columns=['letter', 'number']) df2 = pd.DataFrame([['c', 3], ['d', 4]],columns=['letter', 'number']) df1 df2 pd.concat([df1, df2]) # 将DataFrame具有重叠列的对象合并,缺失值将填充NaN值 df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']], columns=['letter', 'number', 'animal']) pd.concat([df1,df3],sort=False) # 合并DataFrame具有重叠列,并仅通过传递inner给join关键字参数返回那些共享的对象 pd.concat([df1, df3], join="inner") # DataFrame传入,沿x轴水平合并对象axis=1 df4 = pd.DataFrame([['bird', 'polly'], ['monkey', 'george']],columns=['animal', 'name']) pd.concat([df1, df4], axis=1)
纵向合并:纵向堆叠,需要区分情况。
横向合并:横向堆叠,即将两个表在X轴向拼接在一起,可以使用concat函数完成。
merge
panda具有全功能、高性能的内存连接操作,与SQL之类的关系数据库非常相似。与其他开源实现相比,这些方法的性能要好得多(在某些情况下要好一个数量级以上)
pandas提供了merge函数实现高效的内存链接操作:
pd.merge(left, right, how='inner', on=None, left_on=None,right_on=None,left_index=False, right_index=False)
参数名称 | 说明 |
left | 接收DataFrame,左表,无默认。 |
right | 接收DataFrame或Series。右表,无默认。 |
how | {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘inner’ |
on | 接收string或sequence。表示外键字段名。 |
left_on | 关联操作时左表中的关联字段名。 |
right_on | 关联操作时右表中的关联字段名。 |
left_index | 是否将左表的index作为连接主键。(False) |
right_index | 是否将右表的index作为连接主键。(False) |
sort | 是否根据连接键对合并后的数据进行排序。(False) |
suffixes | tuple。合并后左表与右表重叠列名的别名尾缀。默认为(’_x’, ‘_y’)。 |
返回值是一个DataFrame
示例:
import pandas as pd left = pd.DataFrame({ 'student_id':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20], 'student_name': ['Alex', 'Amy', 'Allen', 'Alice', 'Ayoung', 'Billy', 'Brian', 'Bran', 'Bryce', 'Betty', 'Emma', 'Marry', 'Allen', 'Jean', 'Rose', 'David', 'Tom', 'Jack', 'Daniel', 'Andrew'], 'class_id':[1,1,1,2,2,2,3,3,3,4,1,1,1,2,2,2,3,3,3,2], 'gender':['M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F'], 'age':[20,21,22,20,21,22,23,20,21,22,20,21,22,23,20,21,22,20,21,22], 'score':[98,74,67,38,65,29,32,34,85,64,52,38,26,89,68,46,32,78,79,87]}) right = pd.DataFrame( {'class_id':[1,2,3,5], 'class_name': ['ClassA', 'ClassB', 'ClassC', 'ClassE']}) # 合并两个DataFrame data = pd.merge(left,right) print(data)
其他合并方法同数据库相同:
合并方法 | SQL等效 | 描述 |
left | LEFT OUTER JOIN | 使用左侧对象的键 |
right | RIGHT OUTER JOIN | 使用右侧对象的键 |
outer | FULL OUTER JOIN | 使用键的联合 |
inner | INNER JOIN | 使用键的交集 |
实验:
# 合并两个DataFrame (左连接) rs = pd.merge(left,right,on='subject_id', how='left') print(rs) # 合并两个DataFrame (右连接) rs = pd.merge(left,right,on='subject_id', how='right') print(rs) # 合并两个DataFrame (外连接) rs = pd.merge(left,right,on='subject_id', how='outer') print(rs) # 合并两个DataFrame (内连接) rs = pd.merge(left,right,on='subject_id', how='inner') print(rs)
join
连接另一个DataFrame的列。在索引或键列上将列与其他DataFrame连接起来。通过传递列表,一次有效地通过索引连接多个DataFrame对象
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False)
参数说明:
参数名称 | 说明 |
other | DataFrame, Series, or list of DataFrame。索引应与此列中的一列相似。如果传递了Series,则必须设置其name属性,并将其用作结果联接的DataFrame中的列名称。 |
on | str, list of str, or array-like, optional |
how | {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘left’ |
lsuffix | 在左框架的重叠列中使用的后缀 |
rsuffix | 在右框架的重叠列中使用的后缀 |
sort | 通过连接键按字典顺序对结果DataFrame进行排序 |
返回值为一个DataFrame
示例:
df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']}) df other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],'B': ['B0', 'B1', 'B2']}) # 使用其索引加入DataFrames df.join(other, lsuffix='_caller', rsuffix='_other') # 如果要使用键列进行联接,则需要将key设置为df和other的索引 df.set_index('key').join(other.set_index('key')) # 使用键列进行连接的另一种方法是使用on 参数。DataFrame.join始终使用其他索引,但我们可以# 使用df中的任何列 df.join(other.set_index('key'), on='key')
6.Pandas描述性统计分析
a.分组聚合
pandas提供了功能类似于数据库中group by语句的用于拆分数据组的方法pd.groupby();该方法提供的是分组聚合步骤中的拆分功能,能根据索引或字段对数据进行分组(Split) 进而针对得到的多组数据执行聚合操作(Apply),最终合并为最终结果(Combine)。
分组(gorupby)
groupby方法的参数及其说明:
DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=<object object>, observed=False, dropna=True)
参数名称 | 说明 |
by | 接收mapping, function, label, or list of labels。用于确定进行分组的依据。无默认。 |
axis | {0 or ‘index’, 1 or ‘columns’}, default 0 |
level | int, level name, or sequence of such, default None。代表标签所在级别。 |
as_index | 接收bool, default True。表示聚合后的聚合标签是否以DataFrame索引形式输出。 |
sort | 接收boolearn。表示是否对分组依据分组标签进行排序。默认为True。 |
group_keys | 接收boolearn。表示是否显示分组标签的名称。默认为True。 |
squeeze | 接收boolearn。表示是否在允许的情况下对返回数据进行降维。默认为False。 |
observed | bool, default False。 |
dropna | bool, default True。 |
用groupby方法分组后的结果并不能直接查看,而是被存在内存中,输出的是内存地址。实际上分组后的数据对象(Groupby对象)类似Series与DataFrame,是pandas提供的一种对象。
groupby方法的参数及其说明——by参数的特别说明:
如果传入的是一个数组则对其进行计算并分组。
如果传入的是一个字典或者Series 则字典或者Series的值用来做分组依据。
如果传入一个NumPy数组则数据的元素作为分组依据。
如果传入的是列名,字符串或者字符串列表,则使用这些字符串所代表的字段,作为分组依据。
Groupby对象的常用方法:
方法 | 说明 |
groupObject.get_group(‘A’) | 返回A组的详细数据 |
groupObject.size() | 返回每一组的频数 |
grouped = data.groupby(by=['class_id', 'gender']) grouped.get_group((1, 'M')) grouped = data.groupby(by=['class_id', 'gender']) grouped.get_group((1, 'M'))
聚合
聚合函数为每个组返回聚合值。当创建了分组(groupby)对象,就可以对每个分组的其他字段数据执行求和、求标准差等操作。
使用agg函数和aggregate函数聚合计算
在正常使用过程中,agg函数和aggregate函数对DataFrame对象操作时功能几乎完全相 同,因此只需要掌握其中一个函数即可。
DataFrame.agg(func, axis=0, *args, **kwargs) DataFrame.aggregate(func, axis=0, *args, **kwargs)
参数名称 | 说明 |
func | 接收list、dict、function。表示应用于每行/每列的函数。无默认。 |
axis | 接收0或1。代表操作的轴向。默认为0。 |
使用聚合函数agg进行组内计算:
grouped = data.groupby(by='class_id') grouped.agg({'score':np.mean})
对于某个字段希望只做求均值操作,而对另一个字段则希望只做求和操作,可以使用字典的方式,将两个字段名分别作为key:
grouped.agg({'age':np.max, 'score':np.mean})
还可以这样:
result = grouped.agg( {'age':np.max, 'score':[np.mean, np.max]})
使用apply方法聚合数据
使用apply方法对GroupBy对象进行聚合操作其方法和agg方法也相同,不同之处在于apply方法相比agg方法传入的函数只能够作用于整个DataFrame或者Series,而无法像agg一样能够对不同字段应用不同函数获取不同结果。
DataFrame.apply(func, axis=0, broadcast=False, raw=False, reduce=None, args=(), **kwds)
参数名称 | 说明 |
func | 接收functions。表示应用于每行/列的函数。无默认。 |
axis | 接收0或1。代表操作的轴向。默认为0。 |
broadcast | 接收boolearn。表示是否进行广播。默认为False。 |
raw | 接收boolearn。表示是否直接将ndarray对象传递给函数。默认为False。 |
reduce | 接收boolearn或者None。表示返回值的格式。默认None。 |
pandas支持的聚合函数有:
方法名称 | 说明 |
count | 计算分组的数目,包括缺失值。 |
head | 返回每组的前n个值。 |
max | 返回每组最大值。 |
mean | 返回每组的均值。 |
median | 返回每组的中位数。 |
cumcount | 对每个分组中组员的进行标记,0至n-1。 |
size | 返回每组的大小。 |
min | 返回每组最小值。 |
std | 返回每组的标准差。 |
sum | 返回每组的和。 |
b.透视表与交叉表
透视表
透视表(pivot table)是各种电子表格程序和其他数据分析软件中一种常见的数据汇总工具。
它根据一个或多个键对数据进行分组聚合,并根据每个分组进行数据汇总。
使用povit_table函数创建透视表 pivot_table函数常用参数及其说明:
pands.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')
参数名称 | 说明 |
data | 接收DataFrame。表示创建表的数据。无默认。 |
values | 接收字符串。用于指定想要聚合的数据字段名,默认使用全部数据。默认为None。 |
index | 接收string或list。表示行分组键。默认为None。 |
columns | 接收string或list。表示列分组键。默认为None。 |
aggfunc | 接收functions。表示聚合函数。默认为mean。 |
margins | 接收boolearn。表示汇总(Total)功能的开关,设为True后结果集中会出现名为“ALL”的 行和列。默认为True。 |
dropna | 接收boolearn。表示是否删掉全为NaN的列。默认为False。 |
pivot_table函数主要的参数调节 :
index表示透视表的行
columns表示透视表的列
values 表示聚合的数据
aggfunc表示对分析对象进行的分析,一般默认为求平均值,可以指定
margins表示添加每行每列求和的值,默认不添加
# 以class_id与gender做分组汇总数据,默认聚合统计所有列 print(data.pivot_table(index=['class_id', 'gender'])) # 以class_id与gender做分组汇总数据,聚合统计score列 print(data.pivot_table(index=['class_id', 'gender'], values=['score'])) # 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计 print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'])) # 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计 print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'], margins=True)) # 以class_id与gender做分组汇总数据,聚合统计score列,针对age的每个值列级分组统计,添加行、列小计 print(data.pivot_table(index=['class_id', 'gender'], values=['score'], columns=['age'], margins=True, aggfunc='max'))