首页 > 解决方案 > 使用 Pandas 查找 2 个不同大小的数据框之间的差异

问题描述

我有 2 个在不同日期创建的 CSV 文件,我想比较它们并显示保持不变和发生变化的内容。我不知道从哪里开始或如何开始,因为当我尝试不同的合并和连接时,我遇到了数据框大小不同的问题。

df1 :
I    ID            Status         
0   123            Active   
1   124            Active  
2   125            Inactive   
3   126            Active  
4   128            Inactive  
df2: 
I    ID            Status         
0   123            Active   
1   124            Inactive 
2   125            Inactive   
3   126            Active  
4   128            Active
5   129            Active  
6   130            Active   
7   131            Active
8   132            Inactive   

目标是突出从 df1 到 df2 的状态变化,并从 df1 到 df2 保持不变。使用上面的示例,我可能会创建 2 个单独的 Dataframe,如下所示:

df3: (containing all new changes)
I    ID              Status           
1    124             Inactive  
4    128             Active 
5    129             Active  
6    130             Active   
7    131             Active  
df4: (containing all other ‘Active’ one that remained consistent)
I    ID             Status         
0   123             Active     
3   126             Active

为了解释每一行背后的逻辑以及为什么包含在df3中,我将逐行进行,因为我不知道我的示例是否足够清楚

df3:
Index 1 - active to inactive
Index 4 - inactive to active
Index 5 - new active row
Index 6 - new active row
Index 7 - new active row
Index 8 - new inactive row
df4:
Index 0 - remained constant
Index 2 - remained constant
Index 3 - remained constant 

我不知道如何解决这个问题,因为通过合并和连接我遇到了数据框需要相同大小的错误。基本上,我想做的是找到从 df1 到 df2 的变化和保持不变的地方。我有 2 个我正在使用的示例数据集,它们有更多的状态,但想法是一样的。是一个包含两个 csv 文件的谷歌表,updated_values 为 df2,original_values 为 df1。

标签: pythonpandasdataframe

解决方案


您需要执行完全外连接才能从两个数据集中获取所有条目。df2 中所有不在 df1 中的值都将用 NaN 值填充。

df3 = pd.merge(left=df1,right=df2,on='ID',how='outer', indicator=True)

这个新的 df 将包含一个值为 df1 的列“Status_x”和值为 df2 的“Status_y”。然后您可以简单地创建一个名为“更改”的新列来存储更改。您可以使用布尔索引来检查哪些列已更改:

new_rows = df3['_merge'] == 'right_only' # True if the IDs were not in df1
constant = df3['Status_x'] == df3['Status_y'] # True if the Status is the same for both Df

df3['change'] = df3['Status_x'] + ' to ' + df3['Status_y'] # String concatenation to show status change. E.g.: 'Active to Inactive'
df3.loc[new_rows,'change'] = 'New active row' #Sets the value for all new rows
df3.loc[constant,'change'] = 'Remained constant' #Sets the value for columns that remained constant

推荐阅读