使用Pandas按照一列对两个DataFrame进行比较,返回三种不同的输出结果

8

我是Python和编程的初学者。我需要帮助比较两个数据帧,它们长度不同,并且除一个列标签之外,其他列标签也不同。在这两个数据集之间相同的列是我想通过比较数据帧来实现的列。我的数据如下:

    df:  'fruits'  'trees'      'sports'    'countries'  

          bananas   mongolia     basketball    Spain
          grapes    Oak          rugby         Thailand
          oranges   Osage Orange baseball      Egypt
          apples    Maple        golf          Chile

    df2: 'cars'  'flowers'     'countries'    'vegetables'

          Audi    Rose          Spain           Carrots
          BMW     Tulip         Nigeria         Celery
          Honda   Dandelion     Egypt           Onion

我希望能够基于“countries”列比较这两个数据框,并创建三个独立的输出,每个输出都在自己的数据框中。我一直在使用Pandas,并使用pd.concat将df1和df2合并成一个数据框。即使它们不匹配,我也希望保留其余数据框的行。
以下是我期望的输出:
输出# 1:df中不包含在df2中的值:
    d3:  'fruits'  'trees'      'sports'    'countries'  

          grapes    Oak            rugby         Thailand
          apples    Maple          golf          Chile

输出# 2:df2中不在df中的值

        df4: 'cars'  'flowers'   'countries'    'vegetables'

              BMW     Tulip       Nigeria         Celery

输出# 3:df和df2中的值(结合不同数据帧的列)。

df5: 'fruits'  'trees' 'sports'  'cars' 'flowers' 'countries' 'vegetables'  

  bananas   mongolia  basketball   Audi    Rose      Spain    Carrots 
Oranges  Osage Orange baseball    Honda   Dandelion  Egypt    Onion

希望这一切都说得通。 我尝试了很多不同的方法(isin,DataFrame.diff和.difference,df-df2,numpy数组等),我已经搜索了所有地方,但是找不到我正在寻找的确切内容。 非常感谢任何帮助! 谢谢!
1个回答

4

设置参考

from StringIO import StringIO
import pandas as pd

txt1 = """fruits,trees,sports,countries
bananas,mongolia,basketball,Spain
grapes,Oak,rugby,Thailand
oranges,Osage,Orange baseball,Egypt
apples,Maple,golf,Chile"""

txt2 = """cars,flowers,countries,vegetables
Audi,Rose,Spain,Carrots
BMW,Tulip,Nigeria,Celery
Honda,Dandelion,Egypt,Onion"""

df = pd.read_csv(StringIO(txt1))

df2 = pd.read_csv(StringIO(txt2))

解决方案
def outer_parts(df1, df2):
    df3 = df1.merge(df2, indicator=True, how='outer')
    return {n: g.drop('_merge', 1) for n, g in df3.groupby('_merge')}


dfs = outer_parts(df, df2)

Demonstration

dfs['both']

enter image description here

dfs['left_only']

enter image description here

dfs['right_only']

enter image description here


这非常有帮助。不过,如果我想让每个输出都保留所有8列,最好的方法是什么?然后让不匹配的值变成“NaN”。此外,“Both”输出似乎对我无效。在那些既属于df1又属于df2的国家列下面,我似乎得到了空白值。我猜我的两个数据框可能没有任何匹配的国家,而那些匹配的国家在我的数据框中是空白的。所有的值似乎在“_merged”列下要么是“left_only”,要么是“right_only”。在该列中没有任何“both”值。谢谢! - J.L.
df和df1之间有区别吗? - J.L.
dfdf2 是您提供的数据框的名称。outer_parts 函数内部的 df1df2 是它们自己的存在。在这个例子中,我将 dfdf2 传递给函数 outer_parts,然后在函数内部对它们进行操作,作为 df1df2。那就是说...是的,df 在某种程度上相当于 df1,只不过在函数内部。希望我没有搞混事情。 - piRSquared
没问题,现在我明白了。谢谢。@piRSquared 我还有一个问题,脚本中的n:和g代表什么?我只是想确保我理解了Python是如何检索我要查找的输出的。谢谢! - J.L.
我仍然有困难。它没有将df中的“countries”列与df2中的“countries”列进行比较。当我这样做时,结果基本上仍然是这两个数据框。我只得到“both”的项目。 - J.L.
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接