pandas

Merge, join, and concatenate

Syntax#

  • DataFrame.merge(right, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(‘_x’, ‘_y’), copy=True, indicator=False)

  • Merge DataFrame objects by performing a database-style join operation by columns or indexes.

  • If joining columns on columns, the DataFrame indexes will be ignored. Otherwise if joining indexes on indexes or indexes on a column or columns, the index will be passed on.

Parameters#

Parameters Explanation
right DataFrame
how {‘left’, ‘right’, ‘outer’, ‘inner’}, default ‘inner’
left_on label or list, or array-like. Field names to join on in left DataFrame. Can be a vector or list of vectors of the length of the DataFrame to use a particular vector as the join key instead of columns
right_on label or list, or array-like. Field names to join on in right DataFrame or vector/list of vectors per left_on docs
left_index boolean, default False. Use the index from the left DataFrame as the join key(s). If it is a MultiIndex, the number of keys in the other DataFrame (either the index or a number of columns) must match the number of levels
right_index boolean, default False. Use the index from the right DataFrame as the join key. Same caveats as left_index
sort boolean, default Fals. Sort the join keys lexicographically in the result DataFrame
suffixes 2-length sequence (tuple, list, …). Suffix to apply to overlapping column names in the left and right side, respectively
copy boolean, default True. If False, do not copy data unnecessarily
indicator boolean or string, default False. If True, adds a column to output DataFrame called “_merge” with information on the source of each row. If string, column with information on source of each row will be added to output DataFrame, and column will be named value of string. Information column is Categorical-type and takes on a value of “left_only” for observations whose merge key only appears in ‘left’ DataFrame, “right_only” for observations whose merge key only appears in ‘right’ DataFrame, and “both” if the observation’s merge key is found in both.
## Merge
For instance, two tables are given,

T1

id    x        y
8    42        1.9
9    30        1.9

T2

id    signal
8    55
8    56    
8    59
9    57
9    58    
9    60

The goal is to get the new table T3:

id    x        y        s1        s2        s3
8    42        1.9        55        56        58
9    30        1.9        57        58        60

Which is to create columns s1, s2 and s3, each corresponding to a row (the number of rows per id is always fixed and equal to 3)

By applying join (which takes an optional on argument which may be a column or multiple column names, which specifies that the passed DataFrame is to be aligned on that column in the DataFrame). So the solution can be as shown below:

df = df1.merge(df2.groupby(‘id’)[‘signal’].apply(lambda x: x.reset_index(drop=True)).unstack().reset_index())

df
Out[63]: 
   id   x    y   0   1   2
0   8  42  1.9  55  56  59
1   9  30  1.9  57  58  60

If I separate them:

df2t = df2.groupby('id')['signal'].apply(lambda x: x.reset_index(drop=True)).unstack().reset_index()

df2t
Out[59]: 
   id   0   1   2
0   8  55  56  59
1   9  57  58  60

df = df1.merge(df2t)

df
Out[61]: 
   id   x    y   0   1   2
0   8  42  1.9  55  56  59
1   9  30  1.9  57  58  60

Merging two DataFrames

In [1]: df1 = pd.DataFrame({'x': [1, 2, 3], 'y': ['a', 'b', 'c']})

In [2]: df2 = pd.DataFrame({'y': ['b', 'c', 'd'], 'z': [4, 5, 6]})

In [3]: df1
Out[3]: 
   x  y
0  1  a
1  2  b
2  3  c   

In [4]: df2
Out[4]: 
   y  z
0  b  4
1  c  5
2  d  6

Inner join:

Uses the intersection of keys from two DataFrames.

In [5]: df1.merge(df2) # by default, it does an inner join on the common column(s)
Out[5]: 
   x  y  z
0  2  b  4
1  3  c  5

Alternatively specify intersection of keys from two Dataframes.

In [5]: merged_inner = pd.merge(left=df1, right=df2, left_on='y', right_on='y')
Out[5]: 
   x  y  z
0  2  b  4
1  3  c  5

Outer join:

Uses the union of the keys from two DataFrames.

In [6]: df1.merge(df2, how='outer')
Out[6]: 
     x  y    z
0  1.0  a  NaN
1  2.0  b  4.0
2  3.0  c  5.0
3  NaN  d  6.0

Left join:

Uses only keys from left DataFrame.

In [7]: df1.merge(df2, how='left')
Out[7]: 
   x  y    z
0  1  a  NaN
1  2  b  4.0
2  3  c  5.0

Right Join

Uses only keys from right DataFrame.

In [8]: df1.merge(df2, how='right')
Out[8]: 
     x  y  z
0  2.0  b  4
1  3.0  c  5
2  NaN  d  6

Merging / concatenating / joining multiple data frames (horizontally and vertically)

generate sample data frames:

In [57]: df3 = pd.DataFrame({'col1':[211,212,213], 'col2': [221,222,223]})

In [58]: df1 = pd.DataFrame({'col1':[11,12,13], 'col2': [21,22,23]})

In [59]: df2 = pd.DataFrame({'col1':[111,112,113], 'col2': [121,122,123]})

In [60]: df3 = pd.DataFrame({'col1':[211,212,213], 'col2': [221,222,223]})

In [61]: df1
Out[61]:
   col1  col2
0    11    21
1    12    22
2    13    23

In [62]: df2
Out[62]:
   col1  col2
0   111   121
1   112   122
2   113   123

In [63]: df3
Out[63]:
   col1  col2
0   211   221
1   212   222
2   213   223

merge / join / concatenate data frames [df1, df2, df3] vertically - add rows

In [64]: pd.concat([df1,df2,df3], ignore_index=True)
Out[64]:
   col1  col2
0    11    21
1    12    22
2    13    23
3   111   121
4   112   122
5   113   123
6   211   221
7   212   222
8   213   223

merge / join / concatenate data frames horizontally (aligning by index):

In [65]: pd.concat([df1,df2,df3], axis=1)
Out[65]:
   col1  col2  col1  col2  col1  col2
0    11    21   111   121   211   221
1    12    22   112   122   212   222
2    13    23   113   123   213   223

Merge, Join and Concat

Merging key names are same

pd.merge(df1, df2, on='key')

Merging key names are different

pd.merge(df1, df2, left_on='l_key', right_on='r_key')

Different types of joining

pd.merge(df1, df2, on='key', how='left')

Merging on multiple keys

pd.merge(df1, df2, on=['key1', 'key2'])

Treatment of overlapping columns

pd.merge(df1, df2, on='key', suffixes=('_left', '_right'))

Using row index instead of merging keys

pd.merge(df1, df2, right_index=True, left_index=True)

Avoid use of .join syntax as it gives exception for overlapping columns

Merging on left dataframe index and right dataframe column

pd.merge(df1, df2, right_index=True, left_on='l_key')

Concate dataframes

Glued vertically

pd.concat([df1, df2, df3], axis=0)

Glued horizontally

pd.concat([df1, df2, df3], axis=1)

What is the difference between join and merge

Consider the dataframes left and right

left = pd.DataFrame([['a', 1], ['b', 2]], list('XY'), list('AB'))
left

   A  B
X  a  1
Y  b  2

right = pd.DataFrame([['a', 3], ['b', 4]], list('XY'), list('AC'))
right

   A  C
X  a  3
Y  b  4

join
Think of join as wanting to combine to dataframes based on their respective indexes. If there are overlapping columns, join will want you to add a suffix to the overlapping column name from left dataframe. Our two dataframes do have an overlapping column name A.

left.join(right, lsuffix='_')

  A_  B  A  C
X  a  1  a  3
Y  b  2  b  4

Notice the index is preserved and we have 4 columns. 2 columns from left and 2 from right.

If the indexes did not align

left.join(right.reset_index(), lsuffix='_', how='outer')

    A_    B index    A    C
0  NaN  NaN     X    a  3.0
1  NaN  NaN     Y    b  4.0
X    a  1.0   NaN  NaN  NaN
Y    b  2.0   NaN  NaN  NaN

I used an outer join to better illustrate the point. If the indexes do not align, the result will be the union of the indexes.

We can tell join to use a specific column in the left dataframe to use as the join key, but it will still use the index from the right.

left.reset_index().join(right, on='index', lsuffix='_')

  index A_  B  A  C
0     X  a  1  a  3
1     Y  b  2  b  4

merge
Think of merge as aligning on columns. By default merge will look for overlapping columns in which to merge on. merge gives better control over merge keys by allowing the user to specify a subset of the overlapping columns to use with parameter on, or to separately allow the specification of which columns on the left and which columns on the right to merge by.

merge will return a combined dataframe in which the index will be destroyed.

This simple example finds the overlapping column to be 'A' and combines based on it.

left.merge(right)

   A  B  C
0  a  1  3
1  b  2  4

Note the index is [0, 1] and no longer ['X', 'Y']

You can explicitly specify that you are merging on the index with the left_index or right_index paramter

left.merge(right, left_index=True, right_index=True, suffixes=['_', ''])

  A_  B  A  C
X  a  1  a  3
Y  b  2  b  4

And this looks exactly like the join example above.


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow