暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python数据分析笔记#8.2.1 合并数据集

Yuan的学习笔记 2022-01-20
302



「目录」

数据规整:聚合、合并和重塑

Data Wrangling: Join, Combine, and Reshape

  • 8.1 => 层次化索引

  • 8.2 => 合并数据集

   --------> 数据库风格的DataFrame合并

  • 8.3 => 重塑和轴向旋转

公众号的第40篇文章啦,打卡。

因为合并数据集的篇幅蛮长的,还是打算分成几篇笔记更新

那步入正题吧。


数据库风格的DataFrame合并

数据集的合并(merge)或连接(join)运算是通过一个或多个键将行链接起来的。

pandas.merge可根据一个或多个键将不同DataFrame中的行连接起来,来看例子吧。

In [1]: import pandas as pd

In [2]: import numpy as np

In [3]: df1 = pd.DataFrame({'key':['b''b''a''c''a''a''b'], 'data1':range(7)})

In [4]: df2 = pd.DataFrame({'key':['a''b''d'], 'data2':range(3)})

In [5]: df1
Out[5]:
  key  data1
0   b      0
1   b      1
2   a      2
3   c      3
4   a      4
5   a      5
6   b      6

In [6]: df2
Out[6]:
  key  data2
0   a      0
1   b      1
2   d      2

复制

下面是多对一的合并。df1有多个行的键为b和a,df2中key列的每个值仅对应一行,因为key='c'只有df1有,df2没有,所以合并后也没有key='c'的行:

In [7]: pd.merge(df1, df2)
Out[7]:
  key  data1  data2
0   b      0      1
1   b      1      1
2   b      6      1
3   a      2      0
4   a      4      0
5   a      5      0

复制

通过传入on='key'可以指定要用哪个列进行连接,如果没有指定merge会将重复列的列名当作键:

In [8]: pd.merge(df1, df2, on='key')
Out[8]:
  key  data1  data2
0   b      0      1
1   b      1      1
2   b      6      1
3   a      2      0
4   a      4      0
5   a      5      0

复制

如果两个DataFrame的列名不同,也可以分别进行指定:

In [9]: df3 = pd.DataFrame({'lkey':['b''b''a''c''a''a''b'], 'data1':range(7)})

In [10]: df4 = pd.DataFrame({'rkey':['a''b''d'], 'data2':range(3)})

In [11]: df3
Out[11]:
  lkey  data1
0    b      0
1    b      1
2    a      2
3    c      3
4    a      4
5    a      5
6    b      6

In [12]: df4
Out[12]:
  rkey  data2
0    a      0
1    b      1
2    d      2

In [13]: pd.merge(df3, df4, left_on='lkey', right_on='rkey')
Out[13]:
  lkey  data1 rkey  data2
0    b      0    b      1
1    b      1    b      1
2    b      6    b      1
3    a      2    a      0
4    a      4    a      0
5    a      5    a      0

复制

默认情况下,merge做的是“内连接”,结果中的键是交集,所以交集以外的'c'和'd'及与之相关的数据消失了。

其他方式还有"left"、"right"以及“outer”。外连接求取的是键的并集:

In [14]: pd.merge(df1, df2, how='outer')
Out[14]:
  key  data1  data2
0   b    0.0    1.0
1   b    1.0    1.0
2   b    6.0    1.0
3   a    2.0    0.0
4   a    4.0    0.0
5   a    5.0    0.0
6   c    3.0    NaN
7   d    NaN    2.0

复制


上表对不同的链接类型进行了总结,另外'output'应该是'outer'才对


多对多的合并不是很直观。看一下下面的例子吧:

先创建df1和df2,pd.merge中on='key'代表根据df1和df2中的列名'key'连接,how='left'代表使用df1所有的键。

In [15]: df1 = pd.DataFrame({'key':['b''b''a''c''a''b'], 'data1':range(6)})

In [16]: df2 = pd.DataFrame({'key':['a''b''a''b''d'], 'data2':range(5)})

In [17]: df1
Out[17]:
  key  data1
0   b      0
1   b      1
2   a      2
3   c      3
4   a      4
5   b      5

In [18]: df2
Out[18]:
  key  data2
0   a      0
1   b      1
2   a      2
3   b      3
4   d      4

In [19]: pd.merge(df1, df2, on='key', how='left')
Out[19]:
   key  data1  data2
0    b      0    1.0
1    b      0    3.0
2    b      1    1.0
3    b      1    3.0
4    a      2    0.0
5    a      2    2.0
6    c      3    NaN
7    a      4    0.0
8    a      4    2.0
9    b      5    1.0
10   b      5    3.0

复制

原书中作者说多对多的连接产生的是行的笛卡尔积。懂啥意思不

由于左边的DataFrame有3个"b"行,右边的DataFrame有2个"b"行,所以最终结果中就有6个"b"行。

In [24]: frame.loc['a''Ohio']
Out[24]:
color  Green  Red
key2
1          0    1
2          3    4

In [25]: frame.loc['a', ['Ohio''Colorado']]
Out[25]:
state  Ohio     Colorado
color Green Red    Green
key2
1         0   1        2
2         3   4        5

复制

如果我们要根据多个键进行合并,可以传入一个由列名组成的列表

In [21]: left = pd.DataFrame({'key1':['foo''foo''bar'], 'key2':['one''two''one'], 'lval':[1, 2, 3]})

In [22]: right = pd.DataFrame({'key1':['foo''foo''bar''bar'], 'key2':['one''one''one''two'], 'rval':[4, 5,
    ...: 6, 7]})

In [23]: left
Out[23]:
  key1 key2  lval
0  foo  one     1
1  foo  two     2
2  bar  one     3

In [24]: right
Out[24]:
  key1 key2  rval
0  foo  one     4
1  foo  one     5
2  bar  one     6
3  bar  two     7

In [25]: pd.merge(left, right, on=['key1''key2'], how='outer')
Out[25]:
  key1 key2  lval  rval
0  foo  one   1.0   4.0
1  foo  one   1.0   5.0
2  foo  two   2.0   NaN
3  bar  one   3.0   6.0
4  bar  two   NaN   7.0

复制

在合并运算中我们有时还会遇到重复列名的问题。我们可以通过merge中suffixes选项,用于指定附加到左右两个DataFrame对象的重叠列名的字符串

In [26]: left
Out[26]:
  key1 key2  lval
0  foo  one     1
1  foo  two     2
2  bar  one     3

In [27]: right
Out[27]:
  key1 key2  rval
0  foo  one     4
1  foo  one     5
2  bar  one     6
3  bar  two     7


In [28]: pd.merge(left, right, on='key1')
Out[28]:
  key1 key2_x  lval key2_y  rval
0  foo    one     1    one     4
1  foo    one     1    one     5
2  foo    two     2    one     4
3  foo    two     2    one     5
4  bar    one     3    one     6
5  bar    one     3    two     7

In [29]: pd.merge(left, right, on='key1', suffixes=('_left''_right'))
Out[29]:
  key1 key2_left  lval key2_right  rval
0  foo       one     1        one     4
1  foo       one     1        one     5
2  foo       two     2        one     4
3  foo       two     2        one     5
4  bar       one     3        one     6
5  bar       one     3        two     7

复制


merge函数的参数

先更到这里吧,下篇是索引上的合并。

BYE-BYE-BYE-BYE-BYE-BYE,下篇见



-END-


往期回顾


层次化索引




Stay hungry, stay foolish


文章转载自Yuan的学习笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论