Python 熊猫合并101 如何执行(内部|)(左侧|右侧|完整)外部)加入熊猫 如何在合并后为缺少的行添加NAN 合并后如何摆脱NAN 我可以在索引上合并吗 如何合并多个数据帧 与熊猫交叉加入 合并加入concat更新?谁什么?为什么

Python 熊猫合并101 如何执行(内部|)(左侧|右侧|完整)外部)加入熊猫 如何在合并后为缺少的行添加NAN 合并后如何摆脱NAN 我可以在索引上合并吗 如何合并多个数据帧 与熊猫交叉加入 合并加入concat更新?谁什么?为什么,python,pandas,join,merge,concatenation,Python,Pandas,Join,Merge,Concatenation,。。。还有更多。我看到了这些反复出现的问题,它们询问了pandas merge功能的各个方面。今天,关于merge及其各种用例的大部分信息都分散在几十篇措词糟糕、无法检索的文章中。这里的目的是为后代整理一些更重要的观点 本QnA将是一系列关于常用习惯用法的有用用户指南的下一部分(请参阅和,稍后我将讨论) 请注意,这篇文章并不意味着要取代的,所以请阅读,以及!其中一些例子就是从那里摘取的 目录 为便于访问 (先读这篇) 这篇文章旨在向读者介绍SQL风格的熊猫合并、如何使用以及何

。。。还有更多。我看到了这些反复出现的问题,它们询问了pandas merge功能的各个方面。今天,关于merge及其各种用例的大部分信息都分散在几十篇措词糟糕、无法检索的文章中。这里的目的是为后代整理一些更重要的观点

本QnA将是一系列关于常用习惯用法的有用用户指南的下一部分(请参阅和,稍后我将讨论)

请注意,这篇文章并不意味着要取代的,所以请阅读,以及!其中一些例子就是从那里摘取的



目录 为便于访问

  • (先读这篇)


这篇文章旨在向读者介绍SQL风格的熊猫合并、如何使用以及何时不使用

特别是,以下是这篇文章的内容:

  • 基本-连接类型(左、右、外、内)

    • 合并不同的列名
    • 合并多个列
    • 避免输出中重复的合并键列
这篇帖子(以及我在这篇帖子上的其他帖子)将不会通过:

  • 与性能相关的讨论和时间安排(目前)。在适当的情况下,最值得注意的是提到了更好的替代方案
  • 处理后缀、删除额外列、重命名输出和其他特定用例。还有其他(阅读:更好)的帖子处理这个问题,所以想一想吧
注意
除非另有规定,否则大多数示例在演示各种功能时默认使用内部联接操作

# join on `key` column, set as the index first
# For inner join. For left join, omit the "how" argument.
A.set_index('key').join(
    [df.set_index('key') for df in (B, C)], how='inner').reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# join on `key` index
A3.set_index('key').join([B2, C2], how='inner')

       valueA    valueB  valueC
key                            
D    1.454274 -0.977278     1.0
D    0.761038 -0.977278     1.0
此外,这里的所有数据帧都可以复制,因此 你可以和他们一起玩。另外,请参见 关于如何从剪贴板读取数据帧

最后,所有连接操作的可视化表示都是使用Google绘图手工绘制的。灵感来自



说得够多了,告诉我如何使用
merge
! 设置与基础 为了简单起见,键列具有相同的名称(目前)

内部联接表示为

注意
这一点以及即将公布的数字都遵循这一惯例:

  • 蓝色表示合并结果中存在的行
  • 红色表示从结果中排除的行(即已删除)
  • 绿色表示结果中缺少的值被替换为
    NaN
    s
要执行内部联接,请调用左数据帧,将右数据帧和联接键(至少)指定为参数

left.merge(right, on='key')
# Or, if you want to be explicit
# left.merge(right, on='key', how='inner')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278
这将仅返回
中共享公共键的行(在本例中为“B”和“D”)

左外部联接,或左联接由

这可以通过指定
how='left'
来执行

left.merge(right, on='key', how='left')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278
仔细注意此处NaN的位置。如果指定
如何使用
,则只使用
left
中的键,并且
right
中缺少的数据将替换为NaN

同样地,对于一个右外连接,或者是一个右连接,它是

…指定
how='right'

left.merge(right, on='key', how='right')

  key   value_x   value_y
0   B  0.400157  1.867558
1   D  2.240893 -0.977278
2   E       NaN  0.950088
3   F       NaN -0.151357
这里,使用
右侧
的键,将
左侧
缺少的数据替换为NaN

最后,对于完全外部联接,由

指定
how='outer'

left.merge(right, on='key', how='outer')

  key   value_x   value_y
0   A  1.764052       NaN
1   B  0.400157  1.867558
2   C  0.978738       NaN
3   D  2.240893 -0.977278
4   E       NaN  0.950088
5   F       NaN -0.151357
这将使用两个帧中的关键点,并为两个帧中缺少的行插入NAN

文档很好地总结了这些不同的合并:


其他联接-左排除、右排除和完全排除/反联接 如果需要分两步左排除联接右排除联接

对于不包括联接的左侧,表示为

首先执行左外部联接,然后过滤(不包括!)仅来自
的行

(left.merge(right, on='key', how='left', indicator=True)
     .query('_merge == "left_only"')
     .drop('_merge', 1))

  key   value_x  value_y
0   A  1.764052      NaN
2   C  0.978738      NaN
在哪里,

left.merge(right, on='key', how='left', indicator=True)

  key   value_x   value_y     _merge
0   A  1.764052       NaN  left_only
1   B  0.400157  1.867558       both
2   C  0.978738       NaN  left_only
3   D  2.240893 -0.977278       both

关键列的不同名称 如果键列的名称不同,例如,
left
具有
keyLeft
right
具有
keyRight
而不是
key
,则必须将
left\u on
right\u
指定为参数,而不是
上的

left2 = left.rename({'key':'keyLeft'}, axis=1)
right2 = right.rename({'key':'keyRight'}, axis=1)

left2
 
  keyLeft     value
0       A  1.764052
1       B  0.400157
2       C  0.978738
3       D  2.240893

right2

  keyRight     value
0        B  1.867558
1        D -0.977278
2        E  0.950088
3        F -0.151357

避免在输出中重复键列 当从
left
合并
keyLeft
和从
right
合并
keyRight
时,如果您只想在输出中使用
keyLeft
keyRight
(但不能同时使用这两个)中的一个,则可以将索引设置为初始步骤

left3 = left2.set_index('keyLeft')
left3.merge(right2, left_index=True, right_on='keyRight')
    
    value_x keyRight   value_y
0  0.400157        B  1.867558
1  2.240893        D -0.977278
将其与前面命令的输出进行对比(即,
left2.merge(right2,left_on='keyLeft',right_on='keyRight',how='inner')
),您会注意到缺少
keyLeft
。您可以根据将哪个帧的索引设置为键来确定要保留的列。例如,在执行某些外部联接操作时,这可能很重要


仅合并其中一个
数据帧中的一列
例如,考虑

right3 = right.assign(newcol=np.arange(len(right)))
right3
  key     value  newcol
0   B  1.867558       0
1   D -0.977278       1
2   E  0.950088       2
3   F -0.151357       3
如果只需要合并“新值”(不包括任何其他列)
left2.merge(right2, left_on='keyLeft', right_on='keyRight', how='inner')

  keyLeft   value_x keyRight   value_y
0       B  0.400157        B  1.867558
1       D  2.240893        D -0.977278
left3 = left2.set_index('keyLeft')
left3.merge(right2, left_index=True, right_on='keyRight')
    
    value_x keyRight   value_y
0  0.400157        B  1.867558
1  2.240893        D -0.977278
right3 = right.assign(newcol=np.arange(len(right)))
right3
  key     value  newcol
0   B  1.867558       0
1   D -0.977278       1
2   E  0.950088       2
3   F -0.151357       3
left.merge(right3[['key', 'newcol']], on='key')

  key     value  newcol
0   B  0.400157       0
1   D  2.240893       1
# left['newcol'] = left['key'].map(right3.set_index('key')['newcol']))
left.assign(newcol=left['key'].map(right3.set_index('key')['newcol']))

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0
left.merge(right3[['key', 'newcol']], on='key', how='left')

  key     value  newcol
0   A  1.764052     NaN
1   B  0.400157     0.0
2   C  0.978738     NaN
3   D  2.240893     1.0
left.merge(right, on=['key1', 'key2'] ...)
left.merge(right, left_on=['lkey1', 'lkey2'], right_on=['rkey1', 'rkey2'])
import pandas as pd

frames = [Preco2018, Preco2019]

df_merged = pd.concat(frames)
merged = pd.merge(Price, Geo, left_index=True, right_on='Data')
df1.merge(df2, ...).merge(df3, ...)
# Setup.
np.random.seed(0)
A = pd.DataFrame({'key': ['A', 'B', 'C', 'D'], 'valueA': np.random.randn(4)})    
B = pd.DataFrame({'key': ['B', 'D', 'E', 'F'], 'valueB': np.random.randn(4)})
C = pd.DataFrame({'key': ['D', 'E', 'J', 'C'], 'valueC': np.ones(4)})
dfs = [A, B, C] 

# Note, the "key" column values are unique, so the index is unique.
A2 = A.set_index('key')
B2 = B.set_index('key')
C2 = C.set_index('key')

dfs2 = [A2, B2, C2]
# merge on `key` column, you'll need to set the index before concatenating
pd.concat([
    df.set_index('key') for df in dfs], axis=1, join='inner'
).reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# merge on `key` index
pd.concat(dfs2, axis=1, sort=False, join='inner')

       valueA    valueB  valueC
key                            
D    2.240893 -0.977278     1.0
A3 = pd.DataFrame({'key': ['A', 'B', 'C', 'D', 'D'], 'valueA': np.random.randn(5)})
pd.concat([df.set_index('key') for df in [A3, B, C]], axis=1, join='inner')
ValueError: Shape of passed values is (3, 4), indices imply (3, 2)
# join on `key` column, set as the index first
# For inner join. For left join, omit the "how" argument.
A.set_index('key').join(
    [df.set_index('key') for df in (B, C)], how='inner').reset_index()

  key    valueA    valueB  valueC
0   D  2.240893 -0.977278     1.0

# join on `key` index
A3.set_index('key').join([B2, C2], how='inner')

       valueA    valueB  valueC
key                            
D    1.454274 -0.977278     1.0
D    0.761038 -0.977278     1.0
import pandas as pd
import numpy as np

np.random.seed([3, 14])
left = pd.DataFrame(data={'value': np.random.randn(4)}, 
                    index=['A', 'B', 'C', 'D'])    
right = pd.DataFrame(data={'value': np.random.randn(4)},  
                     index=['B', 'D', 'E', 'F'])
left.index.name = right.index.name = 'idxkey'

left
           value
idxkey          
A      -0.602923
B      -0.402655
C       0.302329
D      -0.524349

right
 
           value
idxkey          
B       0.543843
D       0.013135
E      -0.326498
F       1.385076
left.merge(right, left_index=True, right_index=True)

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135
 left.join(right, how='inner', lsuffix='_x', rsuffix='_y')

          value_x   value_y
 idxkey                    
 B      -0.402655  0.543843
 D      -0.524349  0.013135
 left.join(right)
 ValueError: columns overlap but no suffix specified: Index(['value'], dtype='object')
 left.rename(columns={'value':'leftvalue'}).join(right, how='inner')

         leftvalue     value
 idxkey                     
 B       -0.402655  0.543843
 D       -0.524349  0.013135
 pd.concat([left, right], axis=1, sort=False, join='inner')

            value     value
 idxkey                    
 B      -0.402655  0.543843
 D      -0.524349  0.013135
right2 = right.reset_index().rename({'idxkey' : 'colkey'}, axis=1)
right2
 
  colkey     value
0      B  0.543843
1      D  0.013135
2      E -0.326498
3      F  1.385076

left.merge(right2, left_index=True, right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135
left.merge(right, on='idxkey')

         value_x   value_y
idxkey                    
B      -0.402655  0.543843
D      -0.524349  0.013135
left.merge(right2, left_on='idxkey', right_on='colkey')

    value_x colkey   value_y
0 -0.402655      B  0.543843
1 -0.524349      D  0.013135