前不久在咱们技术交换群有群友提到最近他面试阿里70万总包的数据岗位,对方问Pandas
的5
种数据合并的函数,后果他只答出了2
个。
那么,到底是哪五个呢?明天,咱们就来带大家理解一下!
目录:
- concat
- append
- merge
- join
- combine
- 总结
1. concat
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]: s1Out[4]: 0 a1 bdtype: objectIn [5]: s2Out[5]: 0 c1 ddtype: objectIn [6]: pd.concat([s1, s2])Out[6]: 0 a1 b0 c1 ddtype: 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]: letter number0 a 11 b 20 c 31 d 4
横向连贯
In [10]: pd.concat([df1, df2], axis=1)Out[10]: letter number letter number0 a 1 c 31 b 2 d 4
默认状况下,concat
是取并集,如果两个数据中有个数据没有对应行或列,则会填充为空值NaN
。
合并交加
In [11]: df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']], ...: columns=['letter', 'number', 'animal'])In [12]: df1Out[12]: letter number0 a 11 b 2In [13]: df3Out[13]: letter number animal0 c 3 cat1 d 4 dogIn [14]: pd.concat([df1, df3], join='inner')Out[14]: letter number0 a 11 b 20 c 31 d 4
索引重置(不保留原有索引)
In [15]: pd.concat([df1, df3], join='inner', ignore_index=True)Out[15]: letter number0 a 11 b 22 c 33 d 4# 以下形式和上述的输入后果等价In [16]: pd.concat([df1, df3], join='inner').reset_index(drop=True)Out[16]: letter number0 a 11 b 22 c 33 d 4
指定索引
In [17]: pd.concat([df1, df3], keys=['df1','df3'])Out[17]: letter number animaldf1 0 a 1 NaN 1 b 2 NaNdf3 0 c 3 cat 1 d 4 dogIn [18]: pd.concat([df1, df3], keys=['df1','df3'], names=['df名称','行ID'])Out[18]: letter number animaldf名称 行ID df1 0 a 1 NaN 1 b 2 NaNdf3 0 c 3 cat 1 d 4 dog
检测反复
如果索引呈现反复,则无奈通过检测,会报错
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 letter number0 NaN a 11 NaN b 20 cat c 31 dog d 4
DataFrame与Series合并
In [22]: pd.concat([df1, s1])Out[22]: letter number 00 a 1.0 NaN1 b 2.0 NaN0 NaN NaN a1 NaN NaN bIn [23]: pd.concat([df1, s1], axis=1)Out[23]: letter number 00 a 1 a1 b 2 b# 新增列个别可选以下两种形式In [24]: df1.assign(新增列=s1)Out[24]: letter number 新增列0 a 1 a1 b 2 bIn [25]: df1['新增列'] = s1In [26]: df1Out[26]: letter number 新增列0 a 1 a1 b 2 b
以上就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]: letter number0 a 11 b 20 c 31 d 4In [42]: df1.append([df1,df2,df3])Out[42]: letter number animal0 a 1 NaN1 b 2 NaN0 a 1 NaN1 b 2 NaN0 c 3 NaN1 d 4 NaN0 c 3 cat1 d 4 dog
columns重置(不保留原有索引)
In [43]: df1.append([df1,df2,df3], ignore_index=True)Out[43]: letter number animal0 a 1 NaN1 b 2 NaN2 a 1 NaN3 b 2 NaN4 c 3 NaN5 d 4 NaN6 c 3 cat7 d 4 dog
检测反复
如果索引呈现反复,则无奈通过检测,会报错
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 letter number0 NaN a 11 NaN b 20 NaN a 11 NaN b 20 NaN c 31 NaN d 40 cat c 31 dog d 4
追加Series
In [49]: s = pd.Series({'letter':'s1','number':9})In [50]: sOut[50]: letter s1number 9dtype: 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]: letter number0 a 11 b 22 s1 9
追加字典
这个在爬虫的时候比拟好使,每爬取一条数据就合并到DataFrame
相似数据中存储起来
In [54]: dic = {'letter':'s1','number':9}In [55]: df1.append(dic, ignore_index=True)Out[55]: letter number0 a 11 b 22 s1 9
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]: key value2 value10 foo 1 51 bar 2 6
其余连贯形式
In [58]: df1.merge(df2, how='left')Out[58]: key value2 value10 foo 1 5.01 bar 2 6.02 bal 3 NaNIn [59]: df1.merge(df2, how='right')Out[59]: key value2 value10 foo 1.0 51 bar 2.0 62 baz NaN 7In [60]: df1.merge(df2, how='outer')Out[60]: key value2 value10 foo 1.0 5.01 bar 2.0 6.02 bal 3.0 NaN3 baz NaN 7.0In [61]: df1.merge(df2, how='cross')Out[61]: key_x value2 key_y value10 foo 1 foo 51 foo 1 bar 62 foo 1 baz 73 bar 2 foo 54 bar 2 bar 65 bar 2 baz 76 bal 3 foo 57 bal 3 bar 68 bal 3 baz 7
指定连贯键
能够指定单个连贯键,也能够指定多个连贯键
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]: df1Out[64]: lkey1 lkey2 value20 foo a 11 bar b 22 bal c 3In [65]: df2Out[65]: rkey1 rkey2 value20 foo a 51 bar b 62 baz c 7In [66]: df1.merge(df2, left_on='lkey1', right_on='rkey1')Out[66]: lkey1 lkey2 value2_x rkey1 rkey2 value2_y0 foo a 1 foo a 51 bar b 2 bar b 6In [67]: df1.merge(df2, left_on=['lkey1','lkey2'], right_on=['rkey1','rkey2'])Out[67]: lkey1 lkey2 value2_x rkey1 rkey2 value2_y0 foo a 1 foo a 51 bar b 2 bar b 6
指定索引为键
Out[68]: df1.merge(df2, left_index=True, right_index=True)Out[68]: lkey1 lkey2 value2_x rkey1 rkey2 value2_y0 foo a 1 foo a 51 bar b 2 bar b 62 bal c 3 baz c 7
设置反复列后缀
In [69]: df1.merge(df2, left_on='lkey1', right_on='rkey1', suffixes=['左','右'])Out[69]: lkey1 lkey2 value2左 rkey1 rkey2 value2右0 foo a 1 foo a 51 bar b 2 bar b 6
连贯批示
新增一列用于显示数据起源
In [70]: df1.merge(df2, left_on='lkey1', right_on='rkey1', suffixes=['左','右'], how='outer', ...: indicator=True ...: )Out[70]: lkey1 lkey2 value2左 rkey1 rkey2 value2右 _merge0 foo a 1.0 foo a 5.0 both1 bar b 2.0 bar b 6.0 both2 bal c 3.0 NaN NaN NaN left_only3 NaN NaN NaN baz c 7.0 right_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]: dfOut[73]: key A0 K0 A01 K1 A12 K2 A23 K3 A34 K4 A45 K5 A5In [74]: otherOut[74]: key B0 K0 B01 K1 B12 K2 B2In [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]: A Bkey K0 A0 B0K1 A1 B1K2 A2 B2K3 A3 NaNK4 A4 NaNK5 A5 NaNIn [77]: df.join(other.set_index('key'), on='key')Out[77]: key A B0 K0 A0 B01 K1 A1 B12 K2 A2 B23 K3 A3 NaN4 K4 A4 NaN5 K5 A5 NaN
指定反复列后缀
In [78]: df.join(other, lsuffix='_左', rsuffix='右')Out[78]: key_左 A key右 B0 K0 A0 K0 B01 K1 A1 K1 B12 K2 A2 K2 B23 K3 A3 NaN NaN4 K4 A4 NaN NaN5 K5 A5 NaN NaN
其余参数就不多做介绍了,和merge
根本一样。
5. combine
在数据合并的过程中,咱们可能须要对对应地位的值进行肯定的计算,pandas
提供了combine
和combine_first
函数办法来进行这方面的单干操作。
df.combine( other: 'DataFrame', func, fill_value=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]: df1Out[81]: A B0 0 41 0 4In [82]: df2Out[82]: A B0 1 31 1 3In [83]: take_smaller = lambda s1, s2: s1 if s1.sum() < s2.sum() else s2In [84]: df1.combine(df2, take_smaller)Out[84]: A B0 0 31 0 3# 也能够调用numpy的函数In [85]: import numpy as npIn [86]: df1.combine(df2, np.minimum)Out[86]: A B0 0 31 0 3
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]: df1Out[88]: A B0 0 NaN1 0 4.0In [89]: df2Out[89]: A B0 1 31 1 3In [90]: df1.combine(df2, take_smaller, fill_value=-88)Out[90]: A B0 0 -88.01 0 4.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]: df1Out[93]: A B0 0 41 0 4In [94]: df2Out[94]: B C1 3 -102 3 1In [95]: df1.combine(df2, take_smaller)Out[95]: A B C0 NaN NaN NaN1 NaN 3.0 -10.02 NaN 3.0 1.0# 保留A列原有的值In [96]: df1.combine(df2, take_smaller, overwrite=False)Out[96]: A B C0 0.0 NaN NaN1 0.0 3.0 -10.02 NaN 3.0 1.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]: df1Out[99]: A B0 NaN NaN1 0.0 4.0In [100]: df2Out[100]: A B0 1 31 1 3In [101]: df1.combine_first(df2)Out[101]: A B0 1.0 3.01 0.0 4.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]: df1Out[104]: A B0 NaN 4.01 0.0 NaNIn [105]: df2Out[105]: B C1 3 12 3 1In [106]: df1.combine_first(df2)Out[106]: A B C0 NaN 4.0 NaN1 0.0 3.0 1.02 NaN 3.0 1.0
总结
以上就本次介绍的对于Pandas
数据合并的全部内容,相比之下咱们能够发现:
append
次要用于纵向追加数据,比较简单间接;concat
性能最弱小,不仅能够纵向合并数据还能够横向合并数据而且反对很多其余条件设置;merge
则次要用于横向合并数据,相似SQL里的join连贯;join
则比较简单,用于横向合并数据,条件绝对刻薄;combine
更像是依照元素进行合并,依据肯定的条件(函数规定)来进行数据合并。
以上就是本次全部内容,大家感兴趣能够本人试试感受一下。
如果你感觉文章还不错,欢送关注公众号:Python编程学习圈,每日干货分享,发送“J”还可支付大量学习材料。或是返回编程学习网,理解更多编程技术常识。