不平等加入了熊猫?

And*_*rew 8 python merge join dataframe pandas

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

小智 5

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

select d1.something, d2.something else from df1 as d1, df2 as d2 where d1.date=d2.date
Run Code Online (Sandbox Code Playgroud)

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


Par*_*ait 1

Pandas merge()允许两个数据框之间进行outer, left,right连接(不仅仅是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
Run Code Online (Sandbox Code Playgroud)

诚然,交叉连接在这里可能是多余和冗长的,但如果您的不匹配的需求需要跨数据帧进行排列,它会很方便。

  • AFAIK 不在熊猫中。您将必须执行合并和子集的两步组合。 (4认同)