数据合并

数据手拉手

我们经常要从多个渠道获得数据来综合进行分析。例如需要处理几十个甚至更多的数据文件,这需要我们把多个数据源的数据合并在一起。

这里我们需要学习如何利用pandas整合多个DataFrame或者Series中的数据。

数据源介绍

数据源是国家统计局的全国35个主要城市2000年到2017年的理念房价数据。

import pandas as pd
df=pd.read_csv('city_house_price.csv')

df.head(10)
城市2017年2016年2015年2014年2013年2012年2011年2010年2009年2008年2007年2006年2005年2004年2003年2002年2001年2000年
0北京341172848922300184991785416553.4815517.9017151132241164810661.247375.416162.134747.14445644674716.04557.0
1天津15139128709931882883908009.588547.647940660555985575.724649.253987.222950.34239324142308.02274.0
2石家庄973873547798556249434713.544352.153807368826302378.112005.131705.231533.7815701555NaNNaN
3太原882773487303715566686404.746517.477088449937433560.543156.262902.662332.6022041899NaNNaN
4呼和浩特566251964946515346314798.174073.323650324825112458.822175.711540.781430.1612771202NaNNaN
5沈阳794468386416586560745989.455612.965109419638563535.753184.003026.642851.7227532601NaNNaN
6大连1001991198711892178597583.977928.986759617556175417.284256.423579.862972.7426992668NaNNaN
7长春681160186374584757295273.355969.665097401233443118.302408.032271.702118.9719732064NaNNaN
8哈尔滨786163386124575158845112.855216.665196414635152942.742502.862384.042215.1921832157NaNNaN
9上海248662591021501164151619213869.8813565.83142901236481158253.007039.006698.005761.21498940073658.03326.0
df.shape
(35, 19)

concat

concat 解决的是对数据进行合并的问题

例如,现在有3张表格分别存储了1月1号、1月2号和1月3号的订单信息,3张表格包含的列信息完全一致。这个时候我们可以按行对数据进行合并,用一张表格吧3天的数据合并在一起

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZCON3ShX-1586261815356)(./1.gif)]

或者是有另外两张表格,分别存储每个城市本周每天的销售金额和上周每天的销售金额。那我么可以对数据按列进行合并,得到每个城市本周和上周每天的销售金额的数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uvw2pI9E-1586261815358)(./2.gif)]

这两种情况,我们都可以利用concat()方法对数据进行合并。先看一下concat()方法的格式。

pd.concat(objs, axis=0, join='outer', ignore_index=False,
          keys=None, levels=None, names=None, verify_integrity=False,
          copy=True)

objs:列表对象,待合并的DataFrame或者Series,可以包含两个或者两个以上的对象。

axis:用来指定按行(上下拼)还是按列(左右拼)合并,默认按照行进行合并。如果需要按照列进行合并,需要指定参数axis=1

join:确定合并时候记录的匹配方法,后面介绍按列合并的时候会专门展开。

按行进行合并

下面的例子里,我们以文件里读出的原始数据作为基础,生成两个新的DataFrame,然后生成两个新的DataFrame,然后按照行来进行合并。

import pandas as pd
df=pd.read_csv('city_house_price.csv',index_col='城市')
df1=df[0:5]
df2=df[5:10]

df3=pd.concat([df1,df2])
df3
2017年2016年2015年2014年2013年2012年2011年2010年2009年2008年2007年2006年2005年2004年2003年2002年2001年2000年
城市
北京341172848922300184991785416553.4815517.9017151132241164810661.247375.416162.134747.14445644674716.04557.0
天津15139128709931882883908009.588547.647940660555985575.724649.253987.222950.34239324142308.02274.0
石家庄973873547798556249434713.544352.153807368826302378.112005.131705.231533.7815701555NaNNaN
太原882773487303715566686404.746517.477088449937433560.543156.262902.662332.6022041899NaNNaN
呼和浩特566251964946515346314798.174073.323650324825112458.822175.711540.781430.1612771202NaNNaN
沈阳794468386416586560745989.455612.965109419638563535.753184.003026.642851.7227532601NaNNaN
大连1001991198711892178597583.977928.986759617556175417.284256.423579.862972.7426992668NaNNaN
长春681160186374584757295273.355969.665097401233443118.302408.032271.702118.9719732064NaNNaN
哈尔滨786163386124575158845112.855216.665196414635152942.742502.862384.042215.1921832157NaNNaN
上海248662591021501164151619213869.8813565.83142901236481158253.007039.006698.005761.21498940073658.03326.0

按列进行合并

concat()默认按照行进行合并,我们可以通过设定参数axis=1把多个DataFrame按照列来进行合并。

import pandas as pd
df=pd.read_csv('city_house_price.csv',index_col='城市')

df1=df.loc[:,['2017年','2016年','2015年']]
df2=df.loc[:,['2014年','2013年','2012年']]

df3=pd.concat([df1,df2],axis=1)
df3.head
<bound method NDFrame.head of       2017年  2016年  2015年  2014年  2013年     2012年
城市                                               
北京    34117  28489  22300  18499  17854  16553.48
天津    15139  12870   9931   8828   8390   8009.58
石家庄    9738   7354   7798   5562   4943   4713.54
太原     8827   7348   7303   7155   6668   6404.74
呼和浩特   5662   5196   4946   5153   4631   4798.17
沈阳     7944   6838   6416   5865   6074   5989.45
大连    10019   9119   8711   8921   7859   7583.97
长春     6811   6018   6374   5847   5729   5273.35
哈尔滨    7861   6338   6124   5751   5884   5112.85
上海    24866  25910  21501  16415  16192  13869.88
南京    15259  17884  11260  10964  11078   9674.84
杭州    21225  16211  14748  14035  14679  13291.65
宁波    14145  11738  11022  10890  11405  11385.25
合肥    11442   9312   7512   6917   6084   5754.31
福州    10547  11058  11333  10105  10155  10644.52
厦门    28053  25251  18928  17778  14551  12953.38
南昌     8106   7707   6955   6225   6639   5879.99
济南     9712   8405   7527   7158   7013   6650.56
青岛    10052   8997   8437   7855   7987   7583.36
郑州     8323   8093   7223   6579   6587   5643.07
武汉    11453   9819   8404   7399   7238   6895.35
长沙     7287   6160   5544   5458   5759   5602.51
广州    17685  16346  14083  14739  13954  12000.88
深圳    48622  45498  33661  24040  23427  18995.92
南宁     7700   6767   6229   6103   6155   5618.65
海口    11694   8868   7636   7473   7342   6512.03
重庆     6605   5162   5012   5094   5239   4804.80
成都     8595   7377   6584   6536   6708   6678.46
贵阳     6552   5392   4967   4904   4488   4472.69
昆明     8197   6851   7178   6067   5615   5404.90
西安     8166   6385   6221   6105   6435   6224.03
兰州     7137   6162   6089   5860   5520   5420.67
西宁     5890   5007   4602   4807   4380   4304.29
银川     4892   4448   4498   4111   4524   4187.26
乌鲁木齐   6188   5829   6142   5758   5858   5255.04>

索引值的匹配方式

上面在按列对数据进行合并的时候,df1和df2行索引都是城市名称,因为在文件中读取数据的时候,指定了参数index_col为城市,不存在匹配不了的情况。如果两个DataFrame的行索引值不一样,我们如何处理呢?

现在我们来认为的创造两个DataFrame,让它们包含的行索引值不完全一致,看默认情况下pandas如何进行处理。

import pandas as pd

df=pd.read_csv('city_house_price.csv',index_col='城市')

df1=df[['2017年','2016年']].loc[['北京','上海']]
df2=df[['2007年','2006年']].loc[['北京','深圳']]

#按列进行合并
df4=pd.concat([df1,df2],axis=1)
df4
2017年2016年2007年2006年
北京34117.028489.010661.247375.41
上海24866.025910.0NaNNaN
深圳NaNNaN13369.638848.04

这段代码,我们通过读取的文件分别构造了两个DataFrame,以城市字段作为结果的行索引。df1包含了北京和上海两个城市2017和2016年的房价数据,df2包括了北京和深圳两个城市2006和2007年的数据,只有北京这个城市的数据在两个DataFrame中都存在。

合并以后,结果一共包括3条记录。北京这一行合并了df1和df2中的数据,其它城市数据不全的用NaN进行了填充。

这是默认情况下pandas列合并的处理方式,取2个DataFrame行索引的并集,缺失的数据会用空值进行填充。

我们也可以要求pandas在合并时取原始数据行索引的交集,就是行索引同时存在df1和df2中的那些数据会在结果中保留下来。调用concat方法的时候设定join=‘inner’ 就可以实现。

import pandas as pd

df=pd.read_csv('city_house_price.csv',index_col='城市')

df1=df[['2017年','2016年']].loc[['北京','上海']]
df2=df[['2007年','2006年']].loc[['北京','深圳']]

#按列进行合并
df4=pd.concat([df1,df2],axis=1,join='inner')
df4
2017年2016年2007年2006年
城市
北京341172848910661.247375.41

通过程序的运行结果我们看到,合并后的DataFrame只包含了北京这个城市的数据。

除了交集或者并集,我们还可以指定合并后的结果行索引是参与合并的某一个数据的行索引。

比如我们希望取df2的行索引作为合并结果中的索引,我们可以使用DataFrame的reindex()方法,将每个参与concat()操作的DataFrame的行索引都指定为df2的行索引。

import pandas as pd

df=pd.read_csv('city_house_price.csv',index_col='城市')
#准备待合并数据
df1=df[['2017年','2016年']].loc[['北京','上海']]
df2=df[['2007年','2006年']].loc[['北京','深圳','杭州']]
s1=df['2010年'].loc[['北京','深圳','长沙']]
#合并3组数据,以df2行索引值为准
df6=pd.concat([df1.reindex(df2.index),df2,s1.reindex(df2.index)],axis=1)
df6
2017年2016年2007年2006年2010年
城市
北京34117.028489.010661.247375.4117151.0
深圳NaNNaN13369.638848.0418954.0
杭州NaNNaN7431.765967.44NaN

从程序的运行结果中我们看到,合并后的结果包含了北京、深圳、杭州这3个城市的数据,直接使用了df2这个DataFrame的行索引作为结果的行索引。

上面代码中我们还做了些新的尝试,比如,以供有3个数据参与合并,合并的数据中,s1是Series类型的。这是为了向你展示:
1.concat时参与合并的变量没有数目的限制。
2.DataFrame和Series可以一起参与合并。

merge

concat可以很方便的解决合并的问题。除此之外,有另外一种相对复杂的情况。
看一个具体的例子。我们现在有2份数据,第1份数据存储的是订单信息,包含订单号、用户姓名、订单金额等。

第二份数据存储的是用户信息,包括用户姓名、电话号码、地址、用户注册时间等信息。

现在有这样的需求,希望通过订单信息里的用户姓名,在用户信息里获得用户的电话号码、注册时间等信息。

这就是merge可以解决的问题。下面我们来认识一下merge函数和它的参数,对参数具体的使用,在后面会结合案例进行演示和介绍。

pd.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,
         validate=None
         ```

left,right:用于连接的2个DataFrame,用左右来区分。注意merge函数一次只能连接2张表,如果需要连接多张表,可以连续使用多次merge函数。

on: 当两个DataFrame提供的合并列的列名称相同时,只设置on为合并列的列名称就可以。

left_on,right_on:当左右两个DataFrame提供的合并列的列名称不同时,适合使用这两个参数。

<table><tr><td bgcolor=yellow>how</td></tr></table>:连接的方式可以是外连接、内连接、左连接、右连接,默认使用内连接。具体的区别稍后会重点展开。


```python
import pandas as pd
df=pd.read_csv('city_province.csv')
df.head()
cityprovince
0北京北京
1天津天津
2石家庄河北
3太原山西
4呼和浩特内蒙
df3=pd.merge(df1,df2,right_on='city',left_on='城市')
df3
import pandas as pd
df_price=pd.read_csv('city_house_price.csv')
df_province=pd.read_csv('city_province.csv')
df1=df_price.iloc[0:10,0:4]
df2=df_province.iloc[5:15]
df1

城市2017年2016年2015年
0北京341172848922300
1天津15139128709931
2石家庄973873547798
3太原882773487303
4呼和浩特566251964946
5沈阳794468386416
6大连1001991198711
7长春681160186374
8哈尔滨786163386124
9上海248662591021501
df2
cityprovince
5沈阳辽宁
6大连辽宁
7长春吉林
8哈尔滨黑龙江
9上海上海
10南京江苏
11杭州浙江
12宁波浙江
13合肥安徽
14福州福建
df3=pd.merge(df1,df2,right_on='city',left_on='城市')


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值