【问题标题】:Inequality joins in Pandas?不平等加入熊猫?
【发布时间】:2016-06-04 15:08:05
【问题描述】:

我通常使用 Dataframe.merge 来组合 pandas 中的数据帧。据我了解,这仅适用于相等连接。使用其他类型的检查(例如不等式)连接两个数据帧的惯用方法是什么?

【问题讨论】:

    标签: python join pandas merge dataframe


    【解决方案1】:

    Pandas merge() 允许在两个数据框之间进行 outerleftright 连接(不仅仅是 inner 连接),因此您可以返回不匹配的记录。此外,merge() 甚至可以泛化为返回交叉连接(两个数据帧之间的所有组合匹配),然后通过过滤,您可以返回不匹配的记录。还有,还有isin()pandas 方法。

    考虑以下演示。下面是我们喜欢的东西的两个数据框,计算机语言。如图所示,第一个数据帧是第二个数据帧的子集。对于不匹配的列,外连接返回两者中的记录,NaN 可以稍后被过滤掉。交叉连接返回可以过滤的完整行,isin() 在列中搜索值:

    import pandas as pd
    
    df1 = pd.DataFrame({'Languages': ['C++', 'C', 'Java', 'C#', 'Python', 'PHP'],
                        'Uses': ['computing', 'computing', 'application', 'application', 'application', 'web'], 
                        'Type': ['Proprietary', 'Proprietary', 'Proprietary', 'Proprietary', 'Open-Source', 'Open-Source']})
    
    df2 = pd.DataFrame({'Languages': ['C++', 'C', 'Java', 'C#', 'Python', 'PHP',
                                     'Perl', 'R', 'Ruby', 'VB.NET', 'Javascript', 'Matlab'],
                        'Uses': ['computing', 'computing', 'application', 'application', 'application', 'web',
                                'application', 'computing', 'web', 'application', 'web', 'computing'],
                        'Type': ['Proprietary', 'Proprietary', 'Proprietary', 'Proprietary', 'Open-Source',
                                'Open-Source', 'Open-Source', 'Open-Source', 'Open-Source', 'Proprietary',
                                'Open-Source', 'Proprietary']})    
    
    # OUTER JOIN 
    mergedf = pd.merge(df1, df2, on=['Languages'], how='outer')
    # FILTER OUT LANGUAGES IN SMALLER THAT IS NULL
    mergedf = mergedf[pd.isnull(mergedf['Type_x'])][['Languages', 'Uses_y', 'Type_y']]
    
    #     Languages       Uses_y       Type_y
    #6         Perl  application  Open-Source
    #7            R    computing  Open-Source
    #8         Ruby          web  Open-Source
    #9       VB.NET  application  Proprietary
    #10  Javascript          web  Open-Source
    #11      Matlab    computing  Proprietary
    
    
    # ISIN COMPARISON, RETURNING RECORDS IN LARGER NOT IN SMALLER
    unequaldf = df2[~df2.Languages.isin(df1['Languages'])]
    
    #     Languages         Type         Uses
    #6         Perl  Open-Source  application
    #7            R  Open-Source    computing
    #8         Ruby  Open-Source          web
    #9       VB.NET  Proprietary  application
    #10  Javascript  Open-Source          web
    #11      Matlab  Proprietary    computing
    
    
    # CROSS JOIN 
    df1['key'] = 1                 # (REQUIRES A JOIN KEY OF SAME VALUE)
    df2['key'] = 1                    
    crossjoindf = pd.merge(df1, df2, on=['key'])
    # FILTER FOR LANGUAGES IN LARGER NOT IN SMALLER (ALSO USING ISIN)
    crossjoindf = crossjoindf[~crossjoindf['Languages_y'].isin(crossjoindf['Languages_x'])]\
                        [['Languages_y', 'Uses_y', 'Type_y']].drop_duplicates()
    
    #   Languages_y       Uses_y       Type_y
    #6         Perl  application  Open-Source
    #7            R    computing  Open-Source
    #8         Ruby          web  Open-Source
    #9       VB.NET  application  Proprietary
    #10  Javascript          web  Open-Source
    #11      Matlab    computing  Proprietary
    

    诚然,交叉连接在这里可能是多余且冗长的,但如果您的无与伦比的需求需要跨数据帧的排列,它会很方便。

    【讨论】:

    • 那么,没有简单的方法加入不等式吗?
    • AFAIK 不在 Pandas 中。您将不得不做一些合并和子集的两步组合。
    【解决方案2】:

    merge() 相当有限。您可以使用 pandasql.sqldf 完成更复杂的连接。您几乎可以编写任何 sql 查询,并在 sql 语句中将现有数据帧作为表名引用。
    https://github.com/yhat/pandasql/ 一个已知的错误是无法在产品连接中选择多个表,例如

    select d1.something, d2.something else from df1 as d1, df2 as d2 where d1.date=d2.date
    

    但是,如果您可以毫无问题地进行连接,并且我上面的语句可以转换为连接。

    【讨论】:

      猜你喜欢
      • 2023-03-15
      • 2018-05-31
      • 2016-11-25
      • 2018-04-26
      • 2022-08-16
      • 2014-09-21
      • 2020-12-06
      • 2018-11-26
      • 1970-01-01
      相关资源
      最近更新 更多