关于python:Python-关联处理

42次阅读

共计 5375 个字符,预计需要花费 14 分钟才能阅读完成。

将两个表或者多个表关联在一起是常见的运算,这时通常应用 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 可能有新客户,局部内容如下:

老客户数据文件是历年来常常单干的老客户的信息,局部内容如下:

内连贯(inner)

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

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

问题剖析:因为合同数据中可能有新客户,也可能有老客户没有在 2019 年签订合同,所以须要应用内连贯的形式将两表关联。

Python 代码

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

左连贯(left)

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

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

问题剖析:因为不光要求各省老客户的合同金额,还要把新客户作为 unknown 来计算,因而关联的时候须要应用 left 的形式。

Python 代码

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

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

左排除连贯(left_exluding)

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

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

问题剖析,只求新客户,只须要左连贯后,排除掉两表共有键的行就能够了。

Python 代码

探讨:左连贯时,减少参数 indicator,那些两表共有的键的行为 both,左表独有的键的行为 left_only,右表独有的为 right_only。而后筛选出 left_only 标记的行就失去了新客户的行,间接求和失去后果。

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

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

join 函数

Python 代码

探讨:join() 函数关联时,只能应用两表的索引,因而须要先将关联列设置成索引。join 时默认的形式 how=‘left’,这里须要批改为‘inner’。最初求和即可。

concat 函数

问题剖析:concat() 函数关联时,要求关联表的索引是惟一的,这里合同数据的 Client 列有反复,不适宜应用 concat() 函数关联,不过为了更好的了解 concat 函数,咱们对数据中的客户去重,而后再用 concat 连贯。

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

Python 代码

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

多字段关联

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

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

班级表,局部内容如下:

问题五:查问学生的学号、姓名、业余、班级和班主任

问题剖析,要查问学生的学号、姓名、业余、班级和班主任,需将两表依照业余号 majorid 和班级号 classid 进行关联。

Python 代码:

探讨:Pandas 反对多字段关联,只有把要关联的字段放入列表里就能够了。

如果两表的关联字段名不同,如学生表的业余号和班级号是 MAJORID 和 CLASSID。

Python 代码

探讨:merge 函数中应用 left_on 和 right_on 参数即可。

同维关联

表 A 的主键与表 B 的主键关联,他们是一对一的关系,A 和 B 互称为同维表。

(一)多同维表

期末考试成绩表,平时成绩表,选修课成绩表局部内容如下:

期末考试成绩表

平时成绩表

选修课成绩表

问题六:统计学生的学期成绩(期末考试问题、平时成绩、选修课问题所占比例别离是 0.6,0.3,0.1)。

问题剖析:

三张表都是以学生学号为主键,但有的学生可能没有加入某一项的考试,因而可能会有学生短少某一项问题,在关联的时候须要应用外关联的形式。

关联关系如下图:

Python 代码:

探讨:因为三类问题的主键都是学生学号,因而将学号设为索引,而后应用 concat 函数同时关联三张表,使得关联更加快捷。

(二)多层奴才表

表 A 的主键与表 B 的局部主键关联,A 称为主表,B 称为子表。奴才表是多对一的关联关系。

门店信息,订单表,订单明细表局部内容如下:

门店信息表(主表):

订单表(门店信息表的子表,订单明细表的主表):

订单明细表(订单信息表的子表)

问题七:查看各门店各省客户的生产状况和各省门店的销售状况。

问题剖析:1. 订单表和订单明细表关联,其中订单表是主表,订单明细表是子表,关联字段是 [storeid,ordered],关联后分组汇总即得后果。2. 门店信息和第 1 步的汇总后果关联,门店信息表是主表,第 1 步的汇总后果是子表,关联字段是 storeid,关联后分组汇总即得后果。

关联关系如下图:

Python 代码:

探讨:奴才表关联时要一步一步理清关联关系,找准关联字段和需汇总的字段,必要的时候画出关联关系图。本例实际上是两次奴才表关联,每一步关联也能够依照分组汇总——同维关联——分组汇总的形式实现。具体代码如下:

(三)多子表查问

订单表,订单明细表,回款表局部内容如下:

订单表(主表)

订单明细表(子表)

回款表(子表)

问题八:找出未齐全回款的订单

问题剖析:订单表是主表,订单明细表和回款表都是子表,关联的字段是 ordered。留神这里不能够先用主表别离与两个子表关联,再用两个关联后果关联,因为这样做会产生多对多的关联,使得计算错误。正确的做法应该是先对两个子表汇总,而后再别离与主表关联,失去最终的后果。

关联关系如下:

Python 代码:

探讨:两子表汇总后果与订单表的索引雷同,此时能够应用 join 函数或者 concat 函数同时关联多表,最初筛选即可失去后果。

外键关联

表 A 的某些字段与表 B 的主键关联,表 A 的关联字段能够不惟一,表 B 的关联字段惟一,这就是多对一关联,也称作外键关联,即表 A 是事实表,表 B 是维表,A 表中与 B 表主键关联的字段称为 A 指向 B 的外键,B 也称为 A 的外键表。上面介绍几种常见的外键关联实例:

(一)一个事实表,多个不同维表。

销售记录表、城市信息表、产品信息表局部内容如下:

销售记录表 (事实表):

城市信息表(维表 1):

产品信息表(维表 2):

问题九:汇总各个省份各类产品的销售额。

问题剖析:计算各省的各类产品的销售额,须要用销售记录表的 sale_city 和城市信息表的 cityid 关联获取省份的信息,用 product 和产品信息表的 productid 关联获取产品类别信息。

关联关系如下图:

Python 代码

探讨:销售记录表作为事实表,别离与两个维表关联,失去一张宽表,最初对宽表分组汇总即可。

(二)一个事实表,多个维表有维表被屡次应用。

销售记录表,城市信息表局部内容如下:

销售记录表(事实表):

城市信息表(维表):

问题十:找出产品产地与销售地在同一省份的销售记录。

问题剖析:产品产地与销售地都要关联城市信息,从而找到两者在同一省的销售记录,城市信息表被关联了两次。

关联关系如下:

Python 代码:

探讨:第二次关联城市信息时,recitys 的表中曾经有了城市的信息,因而须要设置雷同字段名的后缀,这里把销售地的城市信息加后缀“_s”,产地信息后缀“_p”,最初过滤出两者省份雷同的记录即可。

(三)多层维表

销售记录表、城市信息表、产品信息表局部内容如下:

销售记录表 (事实表):

城市信息表(维表 1):

产品信息表(维表 2):

问题十一:找出产品产地与销售地在同一省份的销售记录。

问题剖析:为获取产品信息,须要用销售记录关联产品信息。关联产品信息后就和例 2 相似了,别离用产地和销售地关联城市信息,过滤后就可失去产品产地与销售地在同一省份的销售记录。

关联关系如下:

Python 代码

探讨:三次关联,1. 销售记录与产品;2. 销售地与城市;3. 产地与城市。最初对三次关联后的后果过滤即可。

(四)自关联

员工信息表局部内容如下:

问题十二:列出所有员工姓名及其间接下级的姓名。

问题剖析:要获取下级的名字须用下级的工号 superior 与员工表的工号 empid 关联。

关联关系如下:

Python 代码

探讨:本人既是事实表又是维表,关联的时候设置后缀即可。

(五)环状关联。

员工信息表,部门信息表局部内容如下:

员工信息表:

部门信息表:

问题十三:找出北京经理的北京员工

问题剖析:首先要关联部门信息表,找到经理字段;而后用经理字段关联员工编号;最初筛选出北京经理的北京员工。

关联关系如图:

Python 代码:

探讨:第一步关联时,员工信息表是事实表,部门信息表是维表;第二步关联时,关联的后果是事实表,员工信息表是维表,这就造成了环状关联。因为员工信息表和部门表都有 name 字段,所以第一步关联时,默认为员工信息表的 name 字段减少了后缀“_x”。

  1. 多表混合关联

现有以下几张表:订单表,订单明细表,产品信息表,员工信息表,出差信息表,客户信息表,城市信息表,他们的表构造与关联关系如下:

问题十四:计算出差工夫大于 10 天的 90 后销售员在各省份销售黑龙江商品的金额。

问题剖析:

多张表关联,要理清下述三个问题:

(1) 关联关系,多对一、一对一、一对多(当产生多对多关联时,多半是错了)。

(2) 关联形式,内连贯、左连贯、右连贯、全连贯。

(3) 关联与解决的程序,先解决(包含过滤和分组)还是先关联。

Python 代码:

探讨:在日常工作中,常常会遇到这种混合的关联,多种关联关系混在一起,理不清其中的关系,会事倍功半甚至失去谬误的后果。

小结

Python 中的关联是将两表依据某个或者某些字段连贯在一起,组成一张宽表,这和 SQL 相似。从上述例子中也能够看出,Python 在解决根底关联和同维关联(问题一至问题八)时,还是比拟不便的,一步一步计算下来,思路清晰,代码也好了解。

然而,对于外键关联,Python 的解决办法有这样一些问题:

1.Python 的 merge 函数一次只能解析一个关联关系,在关联关系较多时比拟麻烦。

  1. 每次解析关联后失去的是一个新表,数据会被复制,耗时且耗内存;这个问题同维表关联时也存在。
  2. 当产生自关联(循环关联)时,其本质还是两表关联失去新表,不能够反复利用曾经建设好的关联关系。

相比之下,esProc SPL 在解决外键关联时要聪慧一些。SPL 会建设外键与主键对象的关联,并没有复制数据自身,这样就能够同时建设多个关联关系,计算快捷且节俭内存,而且产生自关联(循环关联)时,也能够反复利用建好的关联关系,简洁而高效。

比方问题九至十四,SPL 代码写进去是这样的:

问题 SPL 代码简略阐明

当然,SPL 解决同维关联也一样简略,比方问题六至八:

Python 还有一个比较严重的毛病,那就是当数据量大到无奈一次性载入内存时,应用 Python 进行关联运算将是灾难性的,简直所有的关联形式都须要本人手动来实现,波及到外存排序,hash 分段等等简单代码,非高级程序员简直不可能实现。这些代码切实过于繁琐,这里也就没有再给进去。对于大文件的场景,Python 不再适合,还是得用 SPL,它提供有游标对象,能够轻松解决内存装不下的文件之间的关联及其它运算。

比方问题一计算 2019 年轻客户的合同总金额。当合同数据很大,无奈一次性载入内存时,而客户数据能够放入内存时,能够为合同表创立游标来计算,SPL 代码只有区区几行:

两个表都特地大时,SPL 还提供了 joinx() 函数,对有序游标进行关联,能够十分高效的实现大数据的关联工作。

数据包(http://img.raqsoft.com.cn/fil…)

正文完
 0