pandas之数据合并

您所在的位置:网站首页 pandas中数据合并的常用方法 pandas之数据合并

pandas之数据合并

2024-02-21 02:33| 来源: 网络整理| 查看: 265

       在数据处理中,不免会遇到数据之间的合并。学过关系数据库的童鞋应该都清楚数据表之间的连接。今天要说的数据合并其实和数据表之间的连接有很多相似之处。由于 pandas 库在数据分析中比较方便而且用者较多,我们就说pandas中的数据合并方式。

     pandas 中数据合并常用的方法有三种:pandas.merge(), pandas.concat(), 以及实例方法 combine_first()

1)pandas.merge()

merge函数的参数:

left, right参与合并的左、右侧Dataframehowinner、outer、left、right之一,默认是 inneron指定用于连接的列名。如果未指定,则会自动选取要合并数据中相同的列名left_on, right_on左、右侧Dataframe用于连接键的列left_index, right_index将左 \ 右侧的行索引用作连接键sort根据连接键对合并后的数据进行排序,默认True。在处理大数据集的时候,禁用此功能能会有很好的性能提升suffixes字符串元组,用于追加到重复列名的末尾,默认('_x', '_y')copy

设置为False,可以在某些特殊情况下 避免将数据复制到结果数据结构中。默认总是复制。

看几个简单的例子:

In [10]: df1 = pd.DataFrame({'k':['s','s','w','x','x','n','f','c'],'data1':range(8)}) In [11]: df2 = pd.DataFrame({'k':['w','w','s','s','x','f'],'data2':range(6)}) In [12]: pd.merge(df1,df2)  # 未指定合并的列,默认选取两者重复的列 k, 也可以指定 pd.merge(df1,df2,on='k') Out[12]:     data1  k  data2 0      0  s      2 1      0  s      3 2      1  s      2 3      1  s      3 4      2  w      0 5      2  w      1 6      3  x      4 7      4  x      4 8      6  f      5

从上面的结果中会发现有些行消失了,这是因为默认使用的是 inner 连接方式,结果做的交集。可以指定其他的连接方式(参见上面的 how 参数值)。例如:

In [13]: pd.merge(df1,df2,how='outer')   Out[13]:      data1  k  data2 0       0  s    2.0 1       0  s    3.0 2       1  s    2.0 3       1  s    3.0 4       2  w    0.0 5       2  w    1.0 6       3  x    4.0 7       4  x    4.0 8       5  n    NaN 9       6  f    5.0 10      7  c    NaN合并的列名不同时,手动指定要合并的列: In [14]: df2 = pd.DataFrame({'k_1':['w','w','s','s','x','f'] ,'data2':range(6)}) In [17]: pd.merge(df1,df2,left_on='k',right_on='k_1',how='outer') Out[17]:      data1  k  data2  k_1 0       0  s    2.0    s 1       0  s    3.0    s 2       1  s    2.0    s 3       1  s    3.0    s 4       2  w    0.0    w 5       2  w    1.0    w 6       3  x    4.0    x 7       4  x    4.0    x 8       5  n    NaN  NaN 9       6  f    5.0    f 10      7  c    NaN  NaN

根据多个键进行合并,只需要在 on 关键字传入一个列名组成的列表即可:

In [25]: left = pd.DataFrame({'key1': ['foo', 'foo', 'bar'],     ...: 'key2': ['one', 'two', 'one'],'val': [1, 2, 3]}) In [26]: right = pd.DataFrame({'key1': ['foo', 'foo','bar','bar'],     ...: 'key2': ['one', 'one', 'one','two'],'val': [4,5,6,7]}) In [27]: pd.merge(left, right, on=['key1', 'key2'], how='outer') Out[27]:    key1 key2  val_x  val_y 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

从上面的例子中还可以看到,当合并的数据有相同的列时,结果会默认在后面添加_x, _y来区分。也可以手动指定:

In [31]: pd.merge(left, right, on='key1', how='outer',suffixes=('_left','_right')) Out[31]:    key1 key2_left  val_left key2_right  val_right 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 索引作为连接键的合并 有的时候我们要合并的连接键在索引中,这种情况我们就要通过 left_index = True  \ right_index = True 来明确索引作为连接键。 In [35]: df3 = pd.DataFrame({'data3':[5,2,0]},index=list('sxn')) In [36]: df3 Out[36]:     data3 s      5 x      2 n      0 In [37]: pd.merge(df1,df3,left_on='k',right_index=True,how='outer') Out[37]:     data1  k  data3 0      0  s    5.0 1      1  s    5.0 2      2  w    NaN 3      3  x    2.0 4      4  x    2.0 5      5  n    0.0 6      6  f    NaN 7      7  c    NaN

合并层次化索引的数据,必须以列表的形式指明用作合并的列:

In [49]:  lefth = pd.DataFrame({'key1': ['sxn', 'sxn', 'sxn', 'wfc', 'wfc'], 'key2': [2000, 2001, 2002, 2001, 2002],     ...: 'data': np.arange(5.)}) In [50]: righth = pd.DataFrame(np.arange(12).reshape((6, 2)) ,     ...: index=[['wfc', 'wfc', 'sxn', 'sxn', 'sxn', 'snx'],     ...: [2001, 2000, 2000, 2000, 2001, 2002]],     ...: columns=['event1', 'event2']) In [51]: pd.merge(lefth, righth, left_on=['key1', 'key2'],right_index=True, how='outer') Out[51]:     data key1  key2  event1  event2 0   0.0  sxn  2000     4.0     5.0 0   0.0  sxn  2000     6.0     7.0 1   1.0  sxn  2001     8.0     9.0 2   2.0  sxn  2002     NaN     NaN 3   3.0  wfc  2001     0.0     1.0 4   4.0  wfc  2002     NaN     NaN 4   NaN  wfc  2000     2.0     3.0 4   NaN  snx  2002    10.0    11.0 Dataframe 的 join 方法更为方便的实现索引上面的合并 In [62]: df1 = pd.DataFrame({'data1':range(8)},index=['s','s','w','x','x','n','f','c']) In [63]: df2 = pd.DataFrame({'data2':range(4)},index=['s','n','f','c']) In [64]: df1.join(df2) Out[64]:     data1  data2 c      7    3.0 f      6    2.0 n      5    1.0 s      0    0.0 s      1    0.0 w      2    NaN x      3    NaN x      4    NaN In [65]: df3 = pd.DataFrame({'data3':[5,2,0]},index=list('sx     ...: n'))     ...:  In [66]: df1.join([df2,df3]) Out[66]:     data1  data2  data3 c      7    3.0    NaN f      6    2.0    NaN n      5    1.0    0.0 s      0    0.0    5.0 s      1    0.0    5.0 w      2    NaN    NaN x      3    NaN    2.0 x      4    NaN    2.0 2)pandas.concat()

这种连接也是轴向连接,也叫连接,绑定,堆叠。

numpy 中 concatenation函数。

In [68]: arr = np.arange(12).reshape(3,4) In [69]: np.concatenate([arr,arr],axis=1) # 指定连接轴,axis=1 Out[69]:  array([[ 0,  1,  2,  3,  0,  1,  2,  3],        [ 4,  5,  6,  7,  4,  5,  6,  7],        [ 8,  9, 10, 11,  8,  9, 10, 11]]) In [70]: np.concatenate([arr,arr],axis=0) # 指定连接轴,axis=0 Out[70]:  array([[ 0,  1,  2,  3],        [ 4,  5,  6,  7],        [ 8,  9, 10, 11],        [ 0,  1,  2,  3],        [ 4,  5,  6,  7],        [ 8,  9, 10, 11]])

concat的参数:

objs参与连接的pandas的列表或字典,唯一必须的参数axis指明连接的轴向,默认axis=0joininner、outer之一join_axes 指明用于其他n-1条轴上的索引,不执行并集交集运算keys用于形成连接轴上的层次化索引levels指定用于层次化索引各级别上的索引,如果设置了的keys的话names用于创建分级别的名称,如果设置了levels和keys 的话verify_integrity检查结果对象新轴上的重复情况,如果发现引发异常,默认可以重复ignore_index不保留连接轴上的索引,产生一组新索引

下面是一些例子说明以上参数的使用情况:

In [77]: s1 = pd.Series([0,1],index=['a','b']) In [78]: s2 = pd.Series([2,3,4],index=['c','d','e']) In [79]: s3 = pd.Series([5,6],index=['f','g']) In [80]: pd.concat([s1,s2,s3]) # 默认 axis=0 Out[80]:  a    0 b    1 c    2 d    3 e    4 f    5 g    6 dtype: int64 In [81]: pd.concat([s1,s2,s3],axis=1) # 按照 axis=1 进行连接,产生一个Dataframe 对象 Out[81]:       0    1    2 a  0.0  NaN  NaN b  1.0  NaN  NaN c  NaN  2.0  NaN d  NaN  3.0  NaN e  NaN  4.0  NaN f  NaN  NaN  5.0 g  NaN  NaN  6.0 In [90]: s4 = pd.concat([s1*5,s3]) In [91]: pd.concat([s1,s4]) Out[91]:  a    0 b    1 a    0 b    5 f    5 g    6 dtype: int64 In [94]: pd.concat([s1,s4],keys=['s1','s4'])  # 可以区分合并后的结果 Out[94]:  s1  a    0     b    1 s4  a    0     b    5     f    5     g    6 dtype: int64 In [97]: pd.concat([s1,s4],axis=1,keys=['s1','s4'])  # 沿着 axis=1 合并,指定的 keys 就会变成Dataframe的列名 Out[97]:      s1  s4 a  0.0   0 b  1.0   5 f  NaN   5 g  NaN   6 In [92]: pd.concat([s1,s4],axis=1) # 按照 axis=1 进行连接,产生一个Dataframe 对象 Out[92]:       0  1 a  0.0  0 b  1.0  5 f  NaN  5 g  NaN  6 In [93]: pd.concat([s1,s4],axis=1,join='inner') # join='inner' 产生交集 Out[93]:     0  1 a  0  0 b  1  5 In [96]: pd.concat([s1,s4],axis=1,join_axes=[['a','c','b','f']]) # 指定要在其他轴上使用的索引 Out[96]:       0    1 a  0.0  0.0 c  NaN  NaN b  1.0  5.0 f  NaN  5.0

对于Dataframe的合并,逻辑差不多类似:

In [98]: df1 = pd.DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],columns=['one', 'two']) In [99]:  df2 = pd.DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],columns=['three', 'four']) In [100]: pd.concat([df1, df2], axis=1, keys=['level1', 'level2']) Out[100]:    level1     level2      one two  three four a      0   1    5.0  6.0 b      2   3    NaN  NaN c      4   5    7.0  8.0 In [102]: pd.concat([df1, df2], axis=1) Out[102]:     one  two  three  four a    0    1    5.0   6.0 b    2    3    NaN   NaN c    4    5    7.0   8.0 In [101]: pd.concat([df1, df2]) # 不指定轴向。默认axis=0 Out[101]:     four  one  three  two a   NaN  0.0    NaN  1.0 b   NaN  2.0    NaN  3.0 c   NaN  4.0    NaN  5.0 a   6.0  NaN    5.0  NaN c   8.0  NaN    7.0  NaN In [103]: pd.concat([df1, df2],keys=['level1', 'level2']) Out[103]:            four  one  three  two level1 a   NaN  0.0    NaN  1.0        b   NaN  2.0    NaN  3.0        c   NaN  4.0    NaN  5.0 level2 a   6.0  NaN    5.0  NaN        c   8.0  NaN    7.0  NaN In [104]: pd.concat([df1, df2], axis=1, keys=['level1', 'level2'],names=['up','down']) # 用 names 为各分层级别命名 Out[104]:  up   level1     level2 down    one two  three four a         0   1    5.0  6.0 b         2   3    NaN  NaN c         4   5    7.0  8.0 实例方法 combine_first()          还有一种数据组合,简单的说就是数据合并的时候,我有值用我的,我没有值(NA)用你的,都没有那就没有吧。。。这种数据合并,我们先用numpy的where函数解决一下,就知道我上句说的啥意思了。 In [105]: s1 = pd.Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],index=['f', 'e', 'd', 'c', 'b', 'a']) In [107]: s2 = pd.Series(np.arange(len(s1), dtype=np.float64),index=['f', 'e', 'd', 'c', 'b', 'a']) In [108]: s2[-1] = np.nan In [110]: s1 Out[110]:  f    NaN e    2.5 d    NaN c    3.5 b    4.5 a    NaN dtype: float64 In [111]: s2 Out[111]:  f    0.0 e    1.0 d    2.0 c    3.0 b    4.0 a    NaN dtype: float64 In [113]: np.where(pd.isnull(s1),s2,s1) Out[113]: array([0. , 2.5, 2. , 3.5, 4.5, nan]) In [114]: s3 = pd.Series(np.where(pd.isnull(s1),s2,s1),index=s1.index) In [115]: s3 Out[115]:  f    0.0 e    2.5 d    2.0 c    3.5 b    4.5 a    NaN dtype: float64嗯,看到没,大概就是上面这个样子的......

combine_first() 也是实现一样的功能:

In [118]: s2[:-2].combine_first(s1[2:]) Out[118]:  a    NaN b    4.5 c    3.0 d    2.0 e    1.0 f    0.0 dtype: float64

看看Dataframe的 combine_first():

In [119]: df1 = pd.DataFrame({'a': [1., np.nan, 5., np.nan],'b': [np.nan, 2., np.nan, 6.],      ...: 'c': range(2, 18, 4)}) In [120]: df2 = pd.DataFrame({'a': [5., 4., np.nan, 3., 7.],'b': [np.nan, 3., 4., 6., 8.]}) In [121]: df1.combine_first(df2) Out[121]:       a    b     c 0  1.0  NaN   2.0 1  4.0  2.0   6.0 2  5.0  4.0  10.0 3  3.0  6.0  14.0 4  7.0  8.0   NaN


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3