Python 关联处理

本文详细探讨了 Python 中的数据关联处理,包括基础关联(内连接、左连接、左排除连接)、同维关联以及外键关联的各种场景。通过具体的例子展示了如何使用 Pandas 的 merge、join 和 concat 函数进行数据关联,同时也指出 Python 在处理复杂关联时的一些不足,如内存消耗和处理速度,对比了 esProc SPL 的优势。
摘要由CSDN通过智能技术生成

将两个表或者多个表关联在一起是常见的运算,这时通常使用 SQL join 的方式进行关联并进行后续计算。但有时数据并不存储在数据库,而是以文件的形式存储在文件系统,单纯为了计算而把数据存储到数据库有点得不偿失。

Python 的 Pandas 提供了丰富的关联运算函数,能更方便的完成文本文件间的关联计算,现在我们就一起来讨论下 Python 的关联处理。

基础关联

所谓关联是指两张数据表通过某个字段或者某些字段之间存在的某种关系,将两张表以某种条件关联起来。SQL 中的关联可以是等值 JOIN 也可以是非等值 JOIN,所谓非等值 JOIN 就是 JOIN 时的过滤条件不一定是相等的,比如 select A.x,B.y from A join B on A.a<B.b。但在实际工作中这种运算是很少的,绝大多数情况都是等值 JOIN,而且即使遇到非等值 JOIN 的情况,多数情况下也可以转换成等值 JOIN。Python 的 Pandas 中的关联函数都是等值关联的,在这里我们也只讨论等值 JOIN 的情况。

关联的方式有内连接、左连接、右连接、全连接。Pandas 使用 merge() 函数的 how 参数完成,其中 inner:内连接,left:左连接,right:右连接,outer:全连接(默认 how=‘inner’)。下面以一些例子加以说明。

合同数据文件和老客户数据文件分别存储在两份文件中,合同数据文件是 2019 年的合同信息,其中的 Client 可能有新客户,部分内容如下:

ContractNo ActualSale SellDate Product Quantity Amount Client ApplyArea ApplyMethod
10961 8 2019/3/19 52 6 1122 C67350 EastChina SELF_USE
10962 8 2019/3/19 7 45 3584 C67393 SouthChina SELF_USE
10963 9 2019/3/19 60 2 68 C27452 NorthChina RESELL
10964 3 2019/3/20 18 6 2052.5 C77608 SouthChina RESELL
10965 6 2019/3/20 51 16 848 C57885 EastChina SELF_USE
10966 4 2019/3/20 37 8 1255.6 C13113 SouthChina SELF_USE

老客户数据文件是历年来经常合作的老客户的信息,部分内容如下:

ID Name City State Country SalesGoal
C908 ALFKI Shenyang Liaoning China 3
C2262 ANATR Dalian Liaoning China 1
C4352 ANTON Yingkou Liaoning China 10
C4842 AROUT benxi Liaoning China 6
C5505 BERGS Shijiazhuang Hebei China 5

内连接(inner)

内连接,是两表关联后,保留两表共有的键。

问题一:计算老客户 2019 年的合同总金额

问题分析:由于合同数据中可能有新客户,也可能有老客户没有在 2019 年签订合同,所以需要使用内连接的方式将两表关联。

Python 代码

import pandas as pd

contract = pd.read_csv('Contract.csv')

client = pd.read_csv('Client.csv')

join_inner =   pd.merge(contract,client,left_on='Client',right_on='ID')

print(join_inner['Amount'].sum())

导入 pandas

合同数据

客户数据

内连接

 

计算合同总金额

讨论:本例中关联列在两个 dataframe 中列名不同,不能使用 on 参数,而是使用 left_on,左 dataframe 的关联列名,和 right_on,右 dataframe 的关联列名,此时默认的参数 how=’inner’,对关联结果的 Amount 列求和得到结果。

左连接(left)

左连接,指两表关联后,保留左侧表的全部键,右侧表不具备左侧键的列为 nan。

问题二:计算出各省客户的合同金额,新客户的省份用 unknown 表示。

问题分析:因为不光要求各省老客户的合同金额,还要把新客户作为 unknown 来计算,因此关联的时候需要使用 left 的方式。

Python 代码

import pandas as pd

contract = pd.read_csv('Contract.csv')

client =   pd.read_csv('Client.csv',usecols=['ID','State'])

join_left =   pd.merge(contract,client,left_on='Client',right_on='ID',how='left')

join_left.fillna('unknown',inplace=True)

state_amount = join_left.groupby('State',as_index=False).Amount.sum()

print(state_amount)

 

 

 

左连接

 

‘unknown’填补缺失值

 

分组计算各省客户合同金额

讨论:修改默认参数 how=‘inner’为‘left’,实现左连接,保留新客户的合同信息。后续再用‘unknown’填补缺失值,分组求和得到结果。

右连接和全连接的方式就是修改 how=‘right’或者 how=‘outer’。这里就不再一一举例了。

左排除连接(left_exluding)

左排除连接,指两表关联后,只保留左侧键值未在右侧表的键出现的行,右侧表的列为 nan。

问题三:计算新客户的合同总金额

问题分析,只求新客户,只需要左连接后,排除掉两表共有键的行就可以了。

Python 代码

import pandas as pd

contract = pd.read_csv('Contract.csv')

client =   pd.read_csv('Client.csv',usecols=['ID','State'])

join_left = pd.merge(contract,client,left_on='Client',right_on='ID',how='left',indicator=True)

join_left_exluding = join_left.query('_merge ==  "left_only"').drop('_merge', 1)

new_client_amount = join_left_exluding.Amount.sum()

print(new_client_amount)

 

 

 

左连接

 

左排除连接

计算新客户合同金额

讨论:左连接时,增加参数 indicator,那些两表共有的键的行为 both,左表独有的键的行为 left_only,右表独有的为 right_only。然后筛选出 left_only 标记的行就得到了新客户的行,直接求和得到结果。

右排除连接和全排除连接和左排除连接类似,这里也不举例说明了。

Pandas 中的关联函数除了 merge,还有 join 和 concat,我们继续以问题一——计算老客户 2019 年的合同总金额作为案例简单介绍一下这两个函数的使用方法。

join 函数

Python 代码

import pandas as pd

contract =   pd.read_csv('Contract.csv',index_col='Client')

client = pd.read_csv('Client.csv',index_col='ID')

join_inner = contract.join(client,how='inner')

print(join_inner.Amount.sum())

 

导入合同数据,同时设置索引为‘Client’

 

导入客户数据,同时设置索引为‘ID’

使用 join 关联两表

讨论:join() 函数关联时,只能使用两表的索引,因此需要先将关联列设置成索引。join 时默认的方式 how=‘left’,这里需要修改为‘inner’。最后求和即可。

concat 函数

问题分析:concat()函数关联时,要求关联表的索引是唯一的,这里合同数据的 Client 列有重复,不适合使用 concat() 函数关联,不过为了更好的理解 concat 函数,我们对数据中的客户去重,然后再用 concat 连接。

问题四:求老客户 2019 年第一份合同的总金额。

Python 代码

import pandas as pd

contract = pd.read_csv('Contract.csv')

client = pd.read_csv('Client.csv',index_col='ID')

contract = contract.drop_duplicates('Client',   keep='first')

contract.set_index('Client',inplace=True)

join_concat = pd.concat([contract,client],axis=1,   join='inner')

print(join_concat.Amount.sum())

 

 

导入客户数据,同时设置索引为‘ID’

Client列去重

设置 Client 为索引

concat关联

 

讨论:把两个 dataframe 放入列表,axis=1 指按行索引进行关联,默认的 join 方式是 outer,这里改为 inner,最后进行求和。

多字段关联

多字段关联是指两表关联时的键不是单一字段,需要同时关联两个或者更多字段。

现有学生表,部分内容如下:

studentid name majorid classid
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值