大家好,前不久在我们技术交流群有群友提到最近他面试阿里70万总包的数据岗位,对方问Pandas
的5
种数据合并的函数,结果他只答出了2
个。
文章图片
那么,究竟是哪五个呢?今天,我们就来带大家了解一下!想加技术交流群的,文末获取
目录:
- 1. concat
- 2. append
- 3. merge
- 4. join
- 5. combine
- 总结
concat
是pandas
中专门用于数据连接合并的函数,功能非常强大,支持纵向合并和横向合并,默认情况下是纵向合并,具体可以通过参数进行设置。pd.concat(
objs: 'Iterable[NDFrame] | Mapping[Hashable, NDFrame]',
axis=0,
join='outer',
ignore_index: 'bool' = False,
keys=None,
levels=None,
names=None,
verify_integrity: 'bool' = False,
sort: 'bool' = False,
copy: 'bool' = True,
) -> 'FrameOrSeriesUnion'
在函数方法中,各参数含义如下:
接下来,我们就对该函数功能进行演示objs
: 用于连接的数据,可以是DataFrame
或Series
组成的列表
axis=0
: 连接的方式,默认为0也就是纵向连接,可选 1 为横向连接
join='outer'
:合并方式,默认为inner
也就是交集,可选outer
为并集
ignore_index
: 是否保留原有的索引
keys=None
:连接关系,使用传递的值作为一级索引
levels=None
:用于构造多级索引
names=None
:索引的名称
verify_integrity
: 检测索引是否重复,如果为True则有重复索引会报错
sort
: 并集合并方式下,对columns排序
copy
: 是否深度拷贝
基础连接
In [1]: import pandas as pdIn [2]: s1 = pd.Series(['a', 'b'])In [3]: s2 = pd.Series(['c', 'd'])In [4]: s1
Out[4]:
0a
1b
dtype: objectIn [5]: s2
Out[5]:
0c
1d
dtype: objectIn [6]: pd.concat([s1, s2])
Out[6]:
0a
1b
0c
1d
dtype: objectIn [7]: df1 = pd.DataFrame([['a', 1], ['b', 2]],
...:columns=['letter', 'number'])In [8]: df2 = pd.DataFrame([['c', 3], ['d', 4]],
...:columns=['letter', 'number'])In [9]: pd.concat([df1, df2])
Out[9]:
letternumber
0a1
1b2
0c3
1d4
横向连接
In [10]: pd.concat([df1, df2], axis=1)
Out[10]:
letternumber letternumber
0a1c3
1b2d4
默认情况下,
concat
是取并集,如果两个数据中有个数据没有对应行或列,则会填充为空值NaN
。合并交集
In [11]: df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']],
...:columns=['letter', 'number', 'animal'])In [12]: df1
Out[12]:
letternumber
0a1
1b2In [13]: df3
Out[13]:
letternumber animal
0c3cat
1d4dogIn [14]: pd.concat([df1, df3], join='inner')
Out[14]:
letternumber
0a1
1b2
0c3
1d4
索引重置(不保留原有索引)
In [15]: pd.concat([df1, df3], join='inner', ignore_index=True)
Out[15]:
letternumber
0a1
1b2
2c3
3d4
# 以下方式和上述的输出结果等价
In [16]: pd.concat([df1, df3], join='inner').reset_index(drop=True)
Out[16]:
letternumber
0a1
1b2
2c3
3d4
指定索引
In [17]: pd.concat([df1, df3], keys=['df1','df3'])
Out[17]:
letternumber animal
df1 0a1NaN
1b2NaN
df3 0c3cat
1d4dogIn [18]: pd.concat([df1, df3], keys=['df1','df3'], names=['df名称','行ID'])
Out[18]:
letternumber animal
df名称 行ID
df10a1NaN
1b2NaN
df30c3cat
1d4dog
检测重复
如果索引出现重复,则无法通过检测,会报错
In [19]: pd.concat([df1, df3], verify_integrity=True)
Traceback (most recent call last):
...
ValueError: Indexes have overlapping values: Int64Index([0, 1], dtype='int64')
合并并集下columns排序
In [21]: pd.concat([df1, df3], sort=True)
Out[21]:
animal letternumber
0NaNa1
1NaNb2
0catc3
1dogd4
DataFrame与Series合并
In [22]: pd.concat([df1, s1])
Out[22]:
letternumber0
0a1.0NaN
1b2.0NaN
0NaNNaNa
1NaNNaNbIn [23]: pd.concat([df1, s1], axis=1)
Out[23]:
letternumber0
0a1a
1b2b
# 新增列一般可选以下两种方式
In [24]: df1.assign(新增列=s1)
Out[24]:
letternumber 新增列
0a1a
1b2bIn [25]: df1['新增列'] = s1In [26]: df1
Out[26]:
letternumber 新增列
0a1a
1b2b
以上就
concat
函数方法的一些功能,相比之下,另外一个函数append
也可以用于数据追加(纵向合并)2. append
append
主要用于追加数据,是比较简单直接的数据合并方式。df.append(
other,
ignore_index: 'bool' = False,
verify_integrity: 'bool' = False,
sort: 'bool' = False,
) -> 'DataFrame'
在函数方法中,各参数含义如下:
接下来,我们就对该函数功能进行演示other
: 用于追加的数据,可以是DataFrame
或Series
或组成的列表
ignore_index
: 是否保留原有的索引
verify_integrity
: 检测索引是否重复,如果为True则有重复索引会报错
sort
: 并集合并方式下,对columns排序
基础追加
In [41]: df1.append(df2)
Out[41]:
letternumber
0a1
1b2
0c3
1d4In [42]: df1.append([df1,df2,df3])
Out[42]:
letternumber animal
0a1NaN
1b2NaN
0a1NaN
1b2NaN
0c3NaN
1d4NaN
0c3cat
1d4dog
columns重置(不保留原有索引)
In [43]: df1.append([df1,df2,df3], ignore_index=True)
Out[43]:
letternumber animal
0a1NaN
1b2NaN
2a1NaN
3b2NaN
4c3NaN
5d4NaN
6c3cat
7d4dog
检测重复
如果索引出现重复,则无法通过检测,会报错
In [44]: df1.append([df1,df2], verify_integrity=True)
Traceback (most recent call last):
...
ValueError: Indexes have overlapping values: Int64Index([0, 1], dtype='int64')
索引排序
In [46]: df1.append([df1,df2,df3], sort=True)
Out[46]:
animal letternumber
0NaNa1
1NaNb2
0NaNa1
1NaNb2
0NaNc3
1NaNd4
0catc3
1dogd4
【python|5个必知必会的 Python 数据合并技巧】追加Series
In [49]: s = pd.Series({'letter':'s1','number':9})In [50]: s
Out[50]:
letters1
number9
dtype: objectIn [51]: df1.append(s)
Traceback (most recent call last):
...
TypeError: Can only append a Series if ignore_index=True or if the Series has a nameIn [53]: df1.append(s, ignore_index=True)
Out[53]:
letternumber
0a1
1b2
2s19
追加字典
这个在爬虫的时候比较好使,每爬取一条数据就合并到
DataFrame
类似数据中存储起来In [54]: dic = {'letter':'s1','number':9}In [55]: df1.append(dic, ignore_index=True)
Out[55]:
letternumber
0a1
1b2
2s19
3. merge
merge
函数方法类似SQL
里的join
,可以是pd.merge
或者df.merge
,区别就在于后者待合并的数据是pd.merge(
left: 'DataFrame | Series',
right: 'DataFrame | Series',
how: 'str' = 'inner',
on: 'IndexLabel | None' = None,
left_on: 'IndexLabel | None' = None,
right_on: 'IndexLabel | None' = None,
left_index: 'bool' = False,
right_index: 'bool' = False,
sort: 'bool' = False,
suffixes: 'Suffixes' = ('_x', '_y'),
copy: 'bool' = True,
indicator: 'bool' = False,
validate: 'str | None' = None,
) -> 'DataFrame'
在函数方法中,关键参数含义如下:
接下来,我们就对该函数功能进行演示left
: 用于连接的左侧数据
right
: 用于连接的右侧数据
how
: 数据连接方式,默认为 inner,可选outer、left和right
on
: 连接关键字段,左右侧数据中需要都存在,否则就用left_on和right_on
left_on
: 左侧数据用于连接的关键字段
right_on
: 右侧数据用于连接的关键字段
left_index
: True表示左侧索引为连接关键字段
right_index
: True表示右侧索引为连接关键字段
suffixes
: ‘Suffixes’ = (’_x’, ‘_y’),可以自由指定,就是同列名合并后列名显示后缀
indicator
: 是否显示合并后某行数据的归属来源
基础合并
In [55]: df1 = pd.DataFrame({'key': ['foo', 'bar', 'bal'],
...:'value2': [1, 2, 3]})In [56]: df2 = pd.DataFrame({'key': ['foo', 'bar', 'baz'],
...:'value1': [5, 6, 7]})In [57]: df1.merge(df2)
Out[57]:
keyvalue2value1
0foo15
1bar26
其他连接方式
In [58]: df1.merge(df2, how='left')
Out[58]:
keyvalue2value1
0foo15.0
1bar26.0
2bal3NaNIn [59]: df1.merge(df2, how='right')
Out[59]:
keyvalue2value1
0foo1.05
1bar2.06
2bazNaN7In [60]: df1.merge(df2, how='outer')
Out[60]:
keyvalue2value1
0foo1.05.0
1bar2.06.0
2bal3.0NaN
3bazNaN7.0In [61]: df1.merge(df2, how='cross')
Out[61]:
key_xvalue2 key_yvalue1
0foo1foo5
1foo1bar6
2foo1baz7
3bar2foo5
4bar2bar6
5bar2baz7
6bal3foo5
7bal3bar6
8bal3baz7
指定连接键
可以指定单个连接键,也可以指定多个连接键
In [62]: df1 = pd.DataFrame({'lkey1': ['foo', 'bar', 'bal'],
...:'lkey2': ['a', 'b', 'c'],
...:'value2': [1, 2, 3]})In [63]: df2 = pd.DataFrame({'rkey1': ['foo', 'bar', 'baz'],
...:'rkey2': ['a', 'b', 'c'],
...:'value2': [5, 6, 7]})In [64]: df1
Out[64]:
lkey1 lkey2value2
0fooa1
1barb2
2balc3In [65]: df2
Out[65]:
rkey1 rkey2value2
0fooa5
1barb6
2bazc7In [66]: df1.merge(df2, left_on='lkey1', right_on='rkey1')
Out[66]:
lkey1 lkey2value2_x rkey1 rkey2value2_y
0fooa1fooa5
1barb2barb6In [67]: df1.merge(df2, left_on=['lkey1','lkey2'], right_on=['rkey1','rkey2'])
Out[67]:
lkey1 lkey2value2_x rkey1 rkey2value2_y
0fooa1fooa5
1barb2barb6
指定索引为键
Out[68]: df1.merge(df2, left_index=True, right_index=True)
Out[68]:
lkey1 lkey2value2_x rkey1 rkey2value2_y
0fooa1fooa5
1barb2barb6
2balc3bazc7
设置重复列后缀
In [69]: df1.merge(df2, left_on='lkey1', right_on='rkey1', suffixes=['左','右'])
Out[69]:
lkey1 lkey2value2左 rkey1 rkey2value2右
0fooa1fooa5
1barb2barb6
连接指示
新增一列用于显示数据来源
In [70]: df1.merge(df2, left_on='lkey1', right_on='rkey1', suffixes=['左','右'], how='outer',
...:indicator=True
...:)
Out[70]:
lkey1 lkey2value2左 rkey1 rkey2value2右_merge
0fooa1.0fooa5.0both
1barb2.0barb6.0both
2balc3.0NaNNaNNaNleft_only
3NaNNaNNaNbazc7.0right_only
4. join
join
就有点想append
之于concat
,用于数据合并df.join(
other: 'FrameOrSeriesUnion',
on: 'IndexLabel | None' = None,
how: 'str' = 'left',
lsuffix: 'str' = '',
rsuffix: 'str' = '',
sort: 'bool' = False,
) -> 'DataFrame'
在函数方法中,关键参数含义如下:
接下来,我们就对该函数功能进行演示other
: 用于合并的右侧数据
on
: 连接关键字段,左右侧数据中需要都存在,否则就用left_on和right_on
how
: 数据连接方式,默认为 inner,可选outer、left和right
lsuffix
: 左侧同名列后缀
rsuffix
:右侧同名列后缀
In [71]: df = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
...:'A': ['A0', 'A1', 'A2', 'A3', 'A4', 'A5']})In [72]: other = pd.DataFrame({'key': ['K0', 'K1', 'K2'],
...:'B': ['B0', 'B1', 'B2']})In [73]: df
Out[73]:
keyA
0K0A0
1K1A1
2K2A2
3K3A3
4K4A4
5K5A5In [74]: other
Out[74]:
keyB
0K0B0
1K1B1
2K2B2In [75]: df.join(other, on='key')
Traceback (most recent call last):
...
ValueError: You are trying to merge on object and int64 columns. If you wish to proceed you should use pd.concat
如果想用key关键字, 则需要key是索引。。。
指定key
In [76]: df.set_index('key').join(other.set_index('key'))
Out[76]:
AB
key
K0A0B0
K1A1B1
K2A2B2
K3A3NaN
K4A4NaN
K5A5NaNIn [77]: df.join(other.set_index('key'), on='key')
Out[77]:
keyAB
0K0A0B0
1K1A1B1
2K2A2B2
3K3A3NaN
4K4A4NaN
5K5A5NaN
指定重复列后缀
In [78]: df.join(other, lsuffix='_左', rsuffix='右')
Out[78]:
key_左A key右B
0K0A0K0B0
1K1A1K1B1
2K2A2K2B2
3K3A3NaNNaN
4K4A4NaNNaN
5K5A5NaNNaN
其他参数就不多做介绍了,和
merge
基本一样。5. combine 在数据合并的过程中,我们可能需要对对应位置的值进行一定的计算,
pandas
提供了combine
和combine_first
函数方法来进行这方面的合作操作。df.combine(
other: 'DataFrame',
func,
fill_value=https://www.it610.com/article/None,
overwrite:'bool' = True,
) -> 'DataFrame'
比如,数据合并的时候取单元格最小的值
In [79]: df1 = pd.DataFrame({'A': [0, 0], 'B': [4, 4]})In [80]: df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})In [81]: df1
Out[81]:
AB
004
104In [82]: df2
Out[82]:
AB
013
113In [83]: take_smaller = lambda s1, s2: s1 if s1.sum() < s2.sum() else s2In [84]: df1.combine(df2, take_smaller)
Out[84]:
AB
003
103# 也可以调用numpy的函数
In [85]: import numpy as npIn [86]: df1.combine(df2, np.minimum)
Out[86]:
AB
003
103
fill_value填充缺失值
In [87]: df1 = pd.DataFrame({'A': [0, 0], 'B': [None, 4]})In [87]: df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})In [88]: df1
Out[88]:
AB
00NaN
104.0In [89]: df2
Out[89]:
AB
013
113In [90]: df1.combine(df2, take_smaller, fill_value=https://www.it610.com/article/-88)
Out[90]:
AB
00 -88.0
104.0
overwrite=False保留
In [91]: df1 = pd.DataFrame({'A': [0, 0], 'B': [4, 4]})In [92]: df2 = pd.DataFrame({'B': [3, 3], 'C': [-10, 1], }, index=[1, 2])In [93]: df1
Out[93]:
AB
004
104In [94]: df2
Out[94]:
BC
13 -10
231In [95]: df1.combine(df2, take_smaller)
Out[95]:
ABC
0 NaNNaNNaN
1 NaN3.0 -10.0
2 NaN3.01.0
# 保留A列原有的值
In [96]: df1.combine(df2, take_smaller, overwrite=False)
Out[96]:
ABC
00.0NaNNaN
10.03.0 -10.0
2NaN3.01.0
另外一个combine_first
df.combine_first(other: 'DataFrame') -> 'DataFrame'
当df中元素为空采用other里的进行替换,结果为并集合并
In [97]: df1 = pd.DataFrame({'A': [None, 0], 'B': [None, 4]})In [98]: df2 = pd.DataFrame({'A': [1, 1], 'B': [3, 3]})In [99]: df1
Out[99]:
AB
0NaNNaN
10.04.0In [100]: df2
Out[100]:
AB
013
113In [101]: df1.combine_first(df2)
Out[101]:
AB
01.03.0
10.04.0In [102]: df1 = pd.DataFrame({'A': [None, 0], 'B': [4, None]})In [103]: df2 = pd.DataFrame({'B': [3, 3], 'C': [1, 1]}, index=[1, 2])In [104]: df1
Out[104]:
AB
0NaN4.0
10.0NaNIn [105]: df2
Out[105]:
BC
131
231In [106]: df1.combine_first(df2)
Out[106]:
ABC
0NaN4.0NaN
10.03.01.0
2NaN3.01.0
总结 以上就本次介绍的关于
Pandas
数据合并的全部内容,相比之下我们可以发现:-
append
主要用于纵向追加数据,比较简单直接;
-
concat
功能最强大,不仅可以纵向合并数据还可以横向合并数据而且支持很多其他条件设置;
-
merge
则主要用于横向合并数据,类似SQL里的join连接;
-
join
则比较简单,用于横向合并数据,条件相对苛刻;
-
combine
更像是按照元素进行合并,根据一定的条件(函数规则)来进行数据合并。
建议收藏,欢迎点赞、在看~
推荐文章
- 李宏毅《机器学习》国语课程(2022)来了
- 有人把吴恩达老师的机器学习和深度学习做成了中文版
- 上瘾了,最近又给公司撸了一个可视化大屏(附源码)
- 如此优雅,4款 Python 自动数据分析神器真香啊
- 梳理半月有余,精心准备了17张知识思维导图,这次要讲清统计学
- 年终汇总:20份可视化大屏模板,直接套用真香(文末附源码)
文章图片
目前开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友
- 方式①、发送如下图片至微信,长按识别,后台回复:加群;
- 方式②、添加微信号:dkl88191,备注:来自CSDN
- 方式③、微信搜索公众号:Python学习与数据挖掘,后台回复:加群
文章图片
推荐阅读
- python|python 三维数组 txt_python(其他语言也可以)如何保存和拼接三维数组()
- OpeenCV(python)|openCV专栏(一)(基础操作)
- Quant|量化分析师的Python日记【Q Quant兵器谱之函数插值】
- OpenCV|opencv3/python 鼠标响应操作
- pyqt5|pyqt5(12)-模式和非模式对话框-exec-show()
- python date 和 datetime 的取值范围(对比 Mysql 的 datetime 和 timestamp)
- 【python】利用break 和continue退出for循环
- Python中while循环嵌套介绍和3个实例
- 【Python】退出循环的两种不同方式(break和continue)