合并与变形
学习目标
- 知道df.append()、pd.concat()、df.merge()、df.join()四个合并函数的区别和用法
- 知道df.pivot_table()透视表的用法
1 Dataframe合并
很多情况需要将多个df合并为一个新的df,常用方法如下
df1.append(df2)
纵向合并数据集pd.concat([df1, df2, ...])
横向或纵向合并数据集,df1和df2可以没有任何关系, 根据行索引和列名相同合并df1.merge(df2)
横向合并, df1和df2要有关联的列, 类似SQL中的表关联操作df1.join(df2)
横向合并,df1和df2要有相同的索引值才能关联
-
导包并准备数据集
df1 = pd.DataFrame([[1, 2, 3], [1, 10, 20], [5, 6, 7], [3, 9, 0], [8, 0, 3]], columns=['x1', 'x2', 'x3']) df2 = pd.DataFrame([[1, 2], [1, 10], [1, 3], [4, 6], [3, 9]], columns=['x1', 'x4']) print(df1) print(df2) # 输出结果如下 x1 x2 x3 0 1 2 3 1 1 10 20 2 5 6 7 3 3 9 0 4 8 0 3 x1 x4 0 1 2 1 1 10 2 1 3 3 4 6 4 3 9
1.1 df.append函数纵向追加合并df (了解)
df.append()
函数纵向连接其他df重置索引返回新的df
print(df1.append(df2))
# 参数ignore_index默认为False, 如果为True, 则重置自增索引
print(df1.append(df2, ignore_index=True))
# 输出结果如下
x1 x2 x3 x4
0 1 2.0 3.0 NaN
1 1 10.0 20.0 NaN
2 5 6.0 7.0 NaN
3 3 9.0 0.0 NaN
4 8 0.0 3.0 NaN
0 1 NaN NaN 2.0
1 1 NaN NaN 10.0
2 1 NaN NaN 3.0
3 4 NaN NaN 6.0
4 3 NaN NaN 9.0
x1 x2 x3 x4
0 1 2.0 3.0 NaN
1 1 10.0 20.0 NaN
2 5 6.0 7.0 NaN
3 3 9.0 0.0 NaN
4 8 0.0 3.0 NaN
5 1 NaN NaN 2.0
6 1 NaN NaN 10.0
7 1 NaN NaN 3.0
8 4 NaN NaN 6.0
9 3 NaN NaN 9.0
1.2 pd.concat函数纵向横向连接多个数据集
-
pd.concat()
函数纵向连接多个数据集,N个df从上到下一个摞一个:- 不使用
join='inner'
参数,数据会堆叠在一起,列名相同的数据会合并到一列,合并后不存在的数据会用NaN填充 - 使用
join='inner'
参数,只保留数据中的共有部分
- 不使用
-
pd.concat(axis=1)
函数横向连接多个数据集,N个df从左到右一个挨着一个:- 匹配各自行索引,缺失值用NaN表示
- 使用
join='inner'
参数,只保留索引匹配的结果
# 纵向连接,全部数据都保留 print(pd.concat([df1, df2])) # 纵向连接,只保留共有数据 print(pd.concat([df1, df2], join='inner')) # 横向连接,全部数据都保留 print(pd.concat([df1, df2], axis=1)) # 横向连接,保留索引值匹配的数据 print(pd.concat([df1, df2], join='inner', axis=1))
-
pd.concat()
函数纵向连接多个数据集的具体使用print(pd.concat([df1, df2, df3]))
1.3 df.merge合并指定关联列的多个数据集
merge函数能够将df1合并指定列的df2返回新的df,merge函数有2种写法
# 写法1
df1.merge(df2, on='列名', how='固定值')
# 写法2
pd.merge(df1, df2, on='列名', how='固定值')
-
merge函数有2种常用参数,参数说明如下
- 参数
on='列名'
,表示基于哪一列的列值进行合并操作 - 参数
how='固定值'
,表示合并后如何处理行索引,固定参数具体如下:how='left'
对应SQL中的left join,保留左侧表df1中的所有数据how='right'
对应SQL中的right join,保留右侧表df2中的所有数据how='inner'
对应SQL中的inner,只保留左右两侧df1和df2都有的数据how='outer'
对应SQL中的join,保留左右两侧侧表df1和df2中的所有数据
- 参数
-
merge横向连接多个关联数据集具体使用
df3 = pd.merge(df1, df2, how='left', on='x1') df4 = pd.merge(df1, df2, how='right', on='x1') df5 = pd.merge(df1, df2, how='inner', on='x1') df6 = pd.merge(df1, df2, how='outer', on='x1') print(df3) # 下图左1 print(df4) # 下图右上 print(df5) # 下图右中 print(df6) # 下图右下
1.4 df.join横向合并索引值相同的多个数据集
join横向合并索引值相同的多个数据集;通过
lsuffix
和rsuffix
两个参数分别指定左表和右表相同的列名后缀,how参数的用法与merge函数的how参数用法一致
res = df1.join(df2, lsuffix='df1的列名后缀', rsuffix='df2的列名后缀', how='outer')
print(res)
2 Dataframe变形
很多情况需要对原数据集进行一些操作,最终导致数据集的形状发生改变(表格的长宽发生变化),这一类操作称之为df变形
- df.T
- 透视表pivot
- pd.pivot_table
2.1 df.T行列转置
行变列,列变行
print(df1.T)
2.2 df.pivot_table透视表
数据透视表就是基于原数据表、按照一定规则呈现汇总数据,转换各个维度去观察数据;和excel的透视表在数据呈现上功能相同
df.pivot_table(
index='列名1',
columns='列名2',
values='列名3',
aggfunc='内置聚合函数名',
margins=True # 默认是False, 如果为True,就在最后一行和最后一列,按行按列分别执行aggfunc参数规定的聚合函数
)
-
使用说明:以列名1作为索引,根据列名2进行分组,对列名3使用pandas内置的聚合函数进行计算,返回新的df对象
-
参数说明:
- index:返回df的行索引,并依据其做分组;传入原始数据的列名
- columns:返回df的列索引;传入原始数据的列名,根据该列做分组
- values: 要做聚合操作的原始数据的列名
- aggfunc:内置聚合函数名字符串
-
具体使用:加载优衣库的销售数据集,统计每个城市线下门店各种品类商品总销售额
# 读取优衣库的销售数据 df4 = pd.read_csv('../data/uniqlo.csv') # 获取全部线下的销售数据 df5 = df4.query('销售渠道=="线下"') print(df5.head()) # 每个城市线下门店各种品类商品总销售额 res = df5.pivot_table( index='城市', columns='产品名称', values='销售金额', aggfunc='sum', margins=True ) print(res) # 数据结果如下 店铺id 城市 销售渠道 性别 ... 销售金额 订单数量 产品数量 单件成本 0 658 深圳 线下 Female ... 796.0 4 4 59 1 146 杭州 线下 Female ... 149.0 1 1 49 2 70 深圳 线下 Male ... 178.0 2 2 49 3 658 深圳 线下 Female ... 59.0 1 1 49 4 229 深圳 线下 Male ... 65.0 2 3 9 [5 rows x 12 columns] 产品名称 T恤 当季新品 毛衣 ... 运动 配件 All 城市 ... 上海 126778.56 39138.31 18766.67 ... 9119.17 32652.66 275383.64 北京 70349.96 18854.86 7210.68 ... 2214.00 15790.66 130458.62 南京 47702.91 36697.68 7525.10 ... 1406.34 13802.43 123150.93 广州 47157.01 18994.00 10461.00 ... 3929.32 14302.23 117231.19 成都 89127.68 35935.63 15638.33 ... 7678.66 19528.56 208189.86 杭州 253602.43 99377.30 45169.62 ... 23875.08 70574.10 589518.49 武汉 132910.00 64175.42 15849.00 ... 11760.96 23448.75 308357.05 深圳 309042.79 127637.43 44161.03 ... 24339.68 101213.36 733123.68 西安 83574.01 24108.42 17331.74 ... 5629.27 19825.50 180686.61 重庆 96568.24 41494.58 16784.00 ... 9284.50 30133.90 237162.30 All 1256813.59 506413.63 198897.17 ... 99236.98 341272.15 2903262.37 [11 rows x 10 columns]
-
图解上述代码变化过程
-
小练习:统计每个城市线上线下各种不同产品总销售额,不同城市和不同销售渠道为索引值,不同产品名称为列名
res = df4.pivot_table( index=['城市', '销售渠道'], columns='产品名称', values='销售金额', aggfunc='sum', margins=True ) print(res) # 输出结果如下 产品名称 T恤 当季新品 ... 配件 All 城市 销售渠道 ... 上海 线上 48637.48 16136.50 ... 18942.69 114438.09 线下 126778.56 39138.31 ... 32652.66 275383.64 北京 线下 70349.96 18854.86 ... 15790.66 130458.62 南京 线下 47702.91 36697.68 ... 13802.43 123150.93 广州 线上 93729.71 26574.95 ... 28624.54 200893.30 线下 47157.01 18994.00 ... 14302.23 117231.19 成都 线下 89127.68 35935.63 ... 19528.56 208189.86 杭州 线下 253602.43 99377.30 ... 70574.10 589518.49 武汉 线上 120358.13 32243.46 ... 49498.23 281420.73 线下 132910.00 64175.42 ... 23448.75 308357.05 深圳 线下 309042.79 127637.43 ... 101213.36 733123.68 西安 线上 11311.93 4158.34 ... 4177.54 30088.01 线下 83574.01 24108.42 ... 19825.50 180686.61 重庆 线上 7894.00 5138.00 ... 2170.00 26330.35 线下 96568.24 41494.58 ... 30133.90 237162.30 All 1538744.84 590664.88 ... 444685.15 3556432.85 [16 rows x 10 columns]
总结
请对下面的内容 有印象、能找到、能理解、能看懂
-
合并数据集
-
纵向追加合并
df1.append(df2, ignore_index=True)
- 参数ignore_index默认为False, 如果为True, 则重置为自增索引
-
pd.concat函数纵向横向连接多个数据集
# 纵向连接,全部数据都保留 pd.concat([df1, df2]) # 纵向连接,只保留共有数据 pd.concat([df1, df2], join='inner') # 横向连接,全部数据都保留 pd.concat([df1,df2], axis=1) # 横向连接,保留索引值匹配的数据 pd.concat([df1,df2], join='inner', axis=1)
-
df.merge合并指定关联列的多个数据集
df1.merge(df2, on='列名', how='固定值') # 参数on='列名',表示基于那一列进行合并操作 # 参数how='固定值',表示合并后如何处理行索引,固定参数具体如下: # how='left' 对应SQL中的left join,保留左侧表df1中的所有数据 # how='right' 对应SQL中的right join,保留右侧表df2中的所有数据 # how='inner' 对应SQL中的inner,只保留左右两侧df1和df2都有的数据 # how='outer' 对应SQL中的join,保留左右两侧侧表df1和df2中的所有数据
-
df.join横向合并索引值相同的多个数据集;通过
lsuffix
和rsuffix
两个参数分别指定左表和右表相同的列名后缀,how参数的用法与merge函数的how参数用法一致df1.join( df2, lsuffix='df1的列名后缀', rsuffix='df2的列名后缀', how='outer' )
-
合并df的四个函数总结
df1.append(df2)
纵向合并数据集pd.concat([df1,df2])
横向或纵向合并数据集,df1和df2可以没有任何关系df1.merge(df2)
横向合并, df1和df2要有关联的列, 类似SQL中的表关联操作df1.join(df2)
横向合并,df1和df2要有相同的索引值才能关联
-
-
df变形
-
df.T 行变列、列变行
-
df.pivot_table透视表:按照一定规则提取并展示汇总数据,方便我们转换各个维度去观察数据
# 以列名1作为索引 # 根据列名2进行分组 # 对列名3使用pandas内置的聚合函数进行计算 # 返回新的df对象 df.pivot_table( index='列名1', columns='列名2', values='列名3', aggfunc='内置聚合函数名', margins=True # 默认是False, 如果为True,就在最后一行和最后一列,按行按列分别执行aggfunc参数规定的聚合函数 ) # index:返回df的行索引,并依据其做分组;传入原始数据的列名 # columns:返回df的列索引;传入原始数据的列名,根据该列做分组 # values: 要做聚合操作的原始数据的列名 # aggfunc:内置聚合函数名字
-
pivot_table(
index=‘列名1’,
columns=‘列名2’,
values=‘列名3’,
aggfunc=‘内置聚合函数名’,
margins=True # 默认是False, 如果为True,就在最后一行和最后一列,按行按列分别执行aggfunc参数规定的聚合函数
)
# index:返回df的行索引,并依据其做分组;传入原始数据的列名
# columns:返回df的列索引;传入原始数据的列名,根据该列做分组
# values: 要做聚合操作的原始数据的列名
# aggfunc:内置聚合函数名字
```