Python 带条件的左外连接

Python 带条件的左外连接,python,dataframe,Python,Dataframe,我想合并两个数据帧(how=left),但不仅是在索引上,而且是在条件上 例如,假设有两个数据帧 C1 C2 A = I 3 K 2 L 5 C1 C2 C3 B = I 5 T I 0 U K 1 X L 7 Z 现在我想在A.C2>B.C2的条件下,使用索引C1将表A与表B左连接起来。也就是说,最终结果应该是 A.C1 A.C2 B.C2

我想合并两个数据帧(how=left),但不仅是在索引上,而且是在条件上

例如,假设有两个数据帧

      C1 C2 
  A = I  3  
      K  2  
      L  5

      C1 C2 C3
  B = I  5  T
      I  0  U
      K  1  X     
      L  7  Z
现在我想在A.C2>B.C2的条件下,使用索引C1将表A与表B左连接起来。也就是说,最终结果应该是

       A.C1  A.C2 B.C2 B.C3
A<-B = I        1    0    U
       K        2    1    X
       L        5    Null Null

快速而肮脏的解决方案是简单地连接C1列,然后对C2_1>C2_2的所有行将NULL或NaN放入C3。

我发现了一个非本机解决方案:

import pandas as pd
from pandasql import sqldf
pysqldf = lambda q: sqldf(q, globals())

df_A = pd.DataFrame([], columns={'C1', 'C2'})
df_A['C1'] = ['I', 'K', 'L']
df_A['C2'] = [3, 2, 5]
cols = df_A.columns
cols = cols.map(lambda x: x.replace(' ', '_'))
df_A.columns = cols

df_B = pd.DataFrame([], columns={'C1', 'C2', 'C3'})
df_B['C1'] = ['I', 'I', 'K', 'L']
df_B['C2'] = [5, 0, 2, 7]
df_B['C3'] = ['T', 'U', 'X', 'Z']


# df_merge = pd.merge(left=df_A, right=df_B, how='left', on='C1')

df_sql = pysqldf("""
select *
from df_A t_1
left join df_B t_2 on t_1.C1 = t_2.C1 and t_1.C2 >= t_2.C2
;
""")

然而,对于大型表,pandasql的性能却较差

输出:

   C2 C1    C3   C2    C1
0   3  I     U  0.0     I
1   2  K     X  2.0     K
2   5  L  None  NaN  None

方法:使用
pandasql
库将SQL查询直接导入pandas

将熊猫作为pd导入
df_A=pd.DataFrame([],列={'C1','C2'})
df_A['C1']=['I','K']
df_A['C2']=[3,2]
df_B=pd.DataFrame([],列={'C1','C2','C3'})
df_B['C1']=['I','I','K']
df_B['C2']=[5,0,2]
df_B['C3']=['T','U','X']
在我看来,您为在(A.C1=B.C1)上执行外部联接指定的条件没有产生预期的结果。我需要按A.C1执行
分组
,以便在连接后删除A.C1中具有相同值的重复行

将pandasql作为ps导入
q=”“”
选择A.C1作为“A.C1”,
A.C2作为“A.C2”,
B.C2作为“B.C2”,
B.C3为“B.C3”
从df_A作为
左外连接df_B AS B
--在A.C1=B.C1和A.C2=B.C2上
其中A.C2>B.C2
A.C1分组
"""
打印(ps.sqldf(q,locals()))
输出 其他参考资料

  • 请向我们展示您的代码。该链接应该对您有所帮助!-@ShivaPrakash:不,您建议的链接中没有提到条件合并。请看一下[Pandas:Join dataframe with condition]()。其他一些相关链接:(1)、(2)。我扩展了对问题的描述。正如您现在看到的,不幸的是,仅仅用替换值并没有帮助,因为另一个问题是行的重复。这给了我一个错误。在
    选择t_1.C1,t_1.C2,
    的末尾删除逗号以避免它。请立即尝试。仍然缺少的是表B中不匹配时的行为(可能是因为C1不匹配或C2上的条件未满足)。在这些情况下,不应删除,而应使用空值填充右侧。稍后我将相应地修改描述。暂时
       C2 C1    C3   C2    C1
    0   3  I     U  0.0     I
    1   2  K     X  2.0     K
    2   5  L  None  NaN  None
    
      A.C1  A.C2  B.C2 B.C3
    0    I     3     2    X
    1    K     2     0    U