【Python】数据分析.pandas数据预处理.数据组合

网友投稿 235 2022-09-14

【Python】数据分析.pandas数据预处理.数据组合

文章目录

​​数据分析.pandas数据预处理.数据合并​​

​​一、数据堆叠 concat()、append()​​​​二、主键连接 --- join()​​​​三、主键连接 --- merge()​​​​四、重叠合并数据combine_first()​​

数据分析.pandas数据预处理.数据合并

一、数据堆叠 concat()、append()

堆叠就是简单地把两个表拼在一起,也被称作轴向连接、绑定或连接。依照轴的方向,数据堆叠可以分为横向堆叠和纵向堆叠。

concat方法相当于数据库中的全连接(UNION ALL),可以指定按某个轴进行连接。

下面以该表为例演示:

当axis=1的时候,concat作行对齐,然后将不同名称的两张或多张表合并。当两个表的索引不完全一致时,可以使用join来指定连接方式:内连接(inner交集)、外连接(outer并集)。内连接仅仅返回多表间索引重叠的部分,外连接则返回索引的并集部分数据,不足的部分使用空值填补。若多表的索引完全一致时,不论内连接还是外连接,结果都是将表按照x轴向拼接。

import numpy as npimport pandas as pd from sqlalchemy import create_engine# 创建数据库连接engine = create_engine('mysql+pymysql://root:12345678@127.0.0.1:3306/testdb?charset=utf8')# 读取mysql数据detail = pd.read_sql('meal_order_detail1',con=engine)df1 = detail.iloc[:,:10] # 取出前10列数据df2 = detail.iloc[:,10:] # 取出后9列数据print('合并df1的大小为%s,df2的大小为%s。'%(df1.shape,df2.shape))print('外连接后的数据框大小为:',pd.concat([df1,df2],axis=1,join='outer').shape)print('内连接后的数据框大小为:',pd.concat([df1,df2],axis=1,join='inner').shape)合并df1的大小为(2779, 10),df2的大小为(2779, 9)。外连接后的数据框大小为: (2779, 19)内连接后的数据框大小为: (2779, 19)

当axis=0时(默认),concat做列对齐,将不同行索引的两张或多张表纵向合并。当表的列名不完全一致时,同样可以使用join参数:内连接(inner交集)、外连接(outer并集)。内连接仅仅返回多表间索引重叠的部分,外连接则返回索引的并集部分数据,不足的部分使用空值填补。若多表的索引完全一致时,不论内连接还是外连接,结果都是将表按照y轴向拼接。

df3 = detail.iloc[:1500,:] # 取出前1500行数据df4 = detail.iloc[1500:,:] # 取出后1500行数据print('合并df3的大小为%s,df4的大小为%s。'%(df3.shape,df4.shape))print('内连接纵向合并数据后的数据框大小为:',pd.concat([df3,df4],axis=0,join='outer').shape)print('外连接纵向合并数据后的数据框大小为:',pd.concat([df3,df4],axis=0,join='inner').shape)合并df3的大小为(1500, 19),df4的大小为(1279, 19)。内连接纵向合并数据后的数据框大小为: (2779, 19)外连接纵向合并数据后的数据框大小为: (2779, 19)

除了可以使用concat纵向堆叠外,还可以使用append方法实现总向表的堆叠,但前提是两张表的列名必须完全一致。

pandas.DataFrame.append(self,other,ignore_index,verify_integrity=False)

print('合并df3的大小为%s,df4的大小为%s。'%(df3.shape,df4.shape))print('append纵向堆叠后的数据框大小为:',df3.append(df4).shape)合并df3的大小为(1500, 19),df4的大小为(1279, 19)。append纵向堆叠后的数据框大小为: (2779, 19)

​​返回顶部​​

二、主键连接 — join()

join方法提供了一个简便的方法用于将两个DataFrame中的不同的列索引合并成为一个DataFrame。其中参数的意义与merge方法基本相同,只是​​join方法默认为左外连接how=left​​。

import numpy as npimport pandas as pd#创建三个数组t1 = pd.DataFrame(np.ones((2,4)),index=["A","B"],columns=list("abcd"))print(t1)# a b c d# A 1.0 1.0 1.0 1.0# B 1.0 1.0 1.0 1.0t2 = pd.DataFrame(np.ones((3,3)),index=["A","B","c"],columns=list("123"))print(t2)# 1 2 3# A 1.0 1.0 1.0# B 1.0 1.0 1.0# c 1.0 1.0 1.0t3 = pd.DataFrame(np.ones((3,3)),index=["0","1","2"],columns=list("123"))print(t3)# 1 2 3# 0 1.0 1.0 1.0# 1 1.0 1.0 1.0# 2 1.0 1.0 1.0# join()#以最前面的数据为基础,数据的合并默认情况下是把行索引相同的数据合并到一起print(t1.join(t2)) #t1有两行,只合并数据的前两行# a b c d 1 2 3# A 1.0 1.0 1.0 1.0 1.0 1.0 1.0# B 1.0 1.0 1.0 1.0 1.0 1.0 1.0print(t2.join(t1)) #t2有三行,合并数据,缺少的用nan值填补# 1 2 3 a b c d# A 1.0 1.0 1.0 1.0 1.0 1.0 1.0# B 1.0 1.0 1.0 1.0 1.0 1.0 1.0# c 1.0 1.0 1.0 NaN NaN NaN NaNprint(t1.join(t3)) #数据的合并默认情况下是把行索引相同的数据合并到一起,不一样索引的用nan填充# a b c d 1 2 3# A 1.0 1.0 1.0 1.0 NaN NaN NaN# B 1.0 1.0 1.0 1.0 NaN NaN NaN

​​返回顶部​​

三、主键连接 — merge()

pandas提供了一个类似于关系数据库的连接(join)操作的方法merage,可以根据一个或多个键将不同DataFrame中的行连接起来,语法如下:

merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=('_x', '_y'), copy=True, indicator=False)

作为一个功能完善、强大的语言,python的pandas库中的merge()支持各种内外连接。

​​与数据库表的连接操作见博客----MYSQL 的连接~​​在SQL中表的关系: 一对一:在对两个表根据索引相加操作时,索引下的值必须唯一。 多对一:在对两个表进行相加操作时,其中一个表的索引下有一个或者多个相同的值。 多对多:在对两个表进行相加操作时,两个表的索引下有多个相同的值。

表的相加操作其实是对两个表进行笛卡尔乘积运算,然后根据条件筛选。

SELECT *FROM df1INNER JOIN df2ON df1.key = df2.key;或SELECT *FROM df1,df2 where df1.key=df2.key

一对一left = pd.DataFrame({"A":["A0","A1","A2","A3"],"B":["B0","B1","B2","B3"],"Key":["k0","k1","k2","k3"]})right = pd.DataFrame({"C":["C0","C1","C2","C3"],"D":["D0","D1","D2","D3"],"Key":["k0","k1","k2","k3"]})print(left)# A B Key# 0 A0 B0 k0# 1 A1 B1 k1# 2 A2 B2 k2# 3 A3 B3 k3print(right)# C D Key# 0 C0 D0 k0# 1 C1 D1 k1# 2 C2 D2 k2# 3 C3 D3 k3print(pd.merge(left,right,on="Key"))# A B Key C D# 0 A0 B0 k0 C0 D0# 1 A1 B1 k1 C1 D1# 2 A2 B2 k2 C2 D2# 3 A3 B3 k3 C3 D3

通过设置on这个参数来定义在哪个索引值下对两个表进行相加操作。除可以在一个索引值下相加之外,还可以对表在多个索引值下进行相加。

left = pd.DataFrame({"A":["A0","A1","A2","A3"],"B":["B0","B1","B2","B3"],"Key1":["k0","k0","k1","k2"],"Key2":["k0","k1","k0","k1"]})right = pd.DataFrame({"C":["C0","C1","C2","C3"],"D":["D0","D1","D2","D3"],"Key1":["k0","k1","k1","k3"],"Key2":["k0","k0","k0","k0"]})print(left)# A B Key1 Key2# 0 A0 B0 k0 k0# 1 A1 B1 k0 k1# 2 A2 B2 k1 k0# 3 A3 B3 k2 k1print(right)# C D Key1 Key2# 0 C0 D0 k0 k0# 1 C1 D1 k1 k0# 2 C2 D2 k1 k0# 3 C3 D3 k3 k0print(pd.merge(left,right,on=["Key1","Key2"]))# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A2 B2 k1 k0 C1 D1# 2 A2 B2 k1 k0 C2 D2

不论是单索引值还是多索引值下,表的相加都是先生成两个表的笛卡尔乘积,在判断索引值是否相等,将相等的行放入相加的结果中。

how指的是合并(连接)的方式有inner(内连接),left(左外连接),right(右外连 接),outer(全外连接);默认为inner。

left = pd.DataFrame({"A":["A0","A1","A2","A3"],"B":["B0","B1","B2","B3"],"Key1":["k0","k0","k1","k2"],"Key2":["k0","k1","k0","k1"]})right = pd.DataFrame({"C":["C0","C1","C2","C3"],"D":["D0","D1","D2","D3"],"Key1":["k0","k1","k1","k3"],"Key2":["k0","k0","k0","k0"]})print(left)# A B Key1 Key2# 0 A0 B0 k0 k0# 1 A1 B1 k0 k1# 2 A2 B2 k1 k0# 3 A3 B3 k2 k1print(right)# C D Key1 Key2# 0 C0 D0 k0 k0# 1 C1 D1 k1 k0# 2 C2 D2 k1 k0# 3 C3 D3 k3 k0print(pd.merge(left,right,on=["Key1","Key2"])) #默认how=“inner”# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A2 B2 k1 k0 C1 D1# 2 A2 B2 k1 k0 C2 D2print(pd.merge(left,right,on=["Key1","Key2"],how="left")) #左外连接# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A1 B1 k0 k1 NaN NaN# 2 A2 B2 k1 k0 C1 D1# 3 A2 B2 k1 k0 C2 D2# 4 A3 B3 k2 k1 NaN NaNprint(pd.merge(left,right,on=["Key1","Key2"],how="right")) #右外链接# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A2 B2 k1 k0 C1 D1# 2 A2 B2 k1 k0 C2 D2# 3 NaN NaN k3 k0 C3 D3print(pd.merge(left,right,on=["Key1","Key2"],how="inner")) #内连接---交集# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A2 B2 k1 k0 C1 D1# 2 A2 B2 k1 k0 C2 D2print(pd.merge(left,right,on=["Key1","Key2"],how="outer")) #外连接---并集# A B Key1 Key2 C D# 0 A0 B0 k0 k0 C0 D0# 1 A1 B1 k0 k1 NaN NaN# 2 A2 B2 k1 k0 C1 D1# 3 A2 B2 k1 k0 C2 D2# 4 A3 B3 k2 k1 NaN NaN# 5 NaN NaN k3 k0 C3 D3

import numpy as npimport pandas as pd from sqlalchemy import create_engine# 创建数据库连接engine = create_engine('mysql+pymysql://root:12345678@127.0.0.1:3306/testdb?charset=utf8')# 读取mysql、csv数据detail = pd.read_sql('meal_order_detail1',con=engine)order = pd.read_csv('data/meal_order_info.csv',sep=',',encoding='gb18030')# 将info_id转换为字符串格式,为合并做准备order['info_id'] = order['info_id'].astype('str')# 订单详情表和订单信息表均有订单编号--索引一致order_detail = pd.merge(detail,order,left_on='order_id',right_on='info_id')print('detail订单详情表的原始形状为:',detail.shape)print('order订单信息表的原始形状为:',order.shape)print('订单详情表和订单信息表主键合并后的形状为:',order_detail.shape)order_detail.to_csv('data/order_detail.csv',sep=',',index=True)

在合并表的时候,根据detail表和info表的共有id(不考虑重复,detail表如图一id有重复,info表如图二id唯一)合并数据,于是在合并的时候重复id后的空值均以info的数值填充。

当我们将info_id改成order_id,再次执行上面的代码时,结果出现了一丝偏差。因为主键合并,是通过一个或多个键将两个数据集进行连接起来,类似于sql中的join。针对两张包含不同字段的表,将其根据某几个字段一一对应拼接起来,结果集的列数为两个原数据的列数和减去连接键的数量。

import numpy as npimport pandas as pd from sqlalchemy import create_engine# 创建数据库连接engine = create_engine('mysql+pymysql://root:12345678@127.0.0.1:3306/testdb?charset=utf8')# 读取mysql、csv数据detail = pd.read_sql('meal_order_detail1',con=engine)order = pd.read_csv('data/meal_order_info.csv',sep=',',encoding='gb18030')# 将info_id转换为字符串格式,为合并做准备order['order_id'] = order['order_id'].astype('str')# 订单详情表和订单信息表均有订单编号--索引一致#order_detail = pd.merge(detail,order,left_on='order_id',right_on='order_id')order_detail = pd.merge(detail,order,on='order_id')print('detail订单详情表的原始形状为:',detail.shape)print('order订单信息表的原始形状为:',order.shape)print('订单详情表和订单信息表主键合并后的形状为:',order_detail.shape)order_detail.to_csv('data/order_detail.csv',sep=',',index=True)detail订单详情表的原始形状为: (2779, 19)order订单信息表的原始形状为: (945, 21)订单详情表和订单信息表主键合并后的形状为: (2779, 39)

可以清晰地看到此时的连接表只剩下一个order_id,并且合并后的总列数变成了39,与之前不同,当我们把两张表的id设为相同时,使用merge就和join一样,当然仅限于两表所关联的主键一致时。

​​返回顶部​​

四、重叠合并数据combine_first()

有时候,某两份数据的内容完全一致,但是某些特征在其中一张表上是完整的,而在另一张表上的数据则是缺失的。这是除了使用一对一比较填充外,还可以使用重叠合并数据。

pandas.DataFrame.combine_first(other)

参数名称

说明

other

接受DataFrame。表示参与重叠合并的另一个DataFrame。无默认。

#数据填充s1 = pd.Series([2, np.nan, 4, np.nan], index=['A', 'B', 'C', 'D'])s2 = pd.Series([1, 2, 3, 4], index=['A', 'B', 'C', 'D'])# 用 s2 中的数值来填充 s1print(s1.combine_first(s2))'''A 2.0B 2.0C 4.0D 4.0dtype: float64'''df1 = pd.DataFrame({ 'X':[1, np.nan, 3, np.nan], 'Y':[5, np.nan, 7, np.nan], 'Z':[9, np.nan, 11, np.nan]})df2 = pd.DataFrame({ 'Z':[np.nan, 10, np.nan, 12], 'A':[1, 2, 3, 4]})# 功能同样是填充print(df1.combine_first(df2))''' A X Y Z0 1.0 1.0 5.0 9.01 2.0 NaN NaN 10.02 3.0 3.0 7.0 11.03 4.0 NaN NaN 12.0'''

注意: ​​Combine Series values, choosing the calling Series's values first​​.合并时优先选择调用序列的值。

​​返回顶部​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【Vue】Axios 网络请求库
下一篇:休克文案:这8个女性文案,很飒!
相关文章

 发表评论

暂时没有评论,来抢沙发吧~