比较 PandaS DataFrames 并返回第一个缺失的行

Posted

技术标签:

【中文标题】比较 PandaS DataFrames 并返回第一个缺失的行【英文标题】:Compare PandaS DataFrames and return rows that are missing from the first one 【发布时间】:2016-01-25 18:59:33 【问题描述】:

我有 2 个数据帧,想要比较它们并从第一个 (df1) 返回不在第二个 (df2) 中的行。我找到了一种比较它们并返回差异的方法,但不知道如何只返回 df1 中缺失的。

import pandas as pd
from pandas import Series, DataFrame

df1 = pd.DataFrame(  
"City" : ["Chicago", "San Franciso", "Boston"] , 
"State" : ["Illinois", "California", "Massachusett"]  )

df2 = pd.DataFrame(  
"City" : ["Chicago",  "Mmmmiami", "Dallas" , "Omaha"] , 
"State" : ["Illinois", "Florida", "Texas", "Nebraska"]  )



df = pd.concat([df1, df2])
df = df.reset_index(drop=True)

df_gpby = df.groupby(list(df.columns))
idx = [x[0] for x in df_gpby.groups.values() if len(x) == 1]
blah = df.reindex(idx)

【问题讨论】:

你可以更具体一点。问题是什么?问题出在哪里? ... 【参考方案1】:

IIUC 如果您使用的是熊猫版本0.17.0,那么您可以使用merge 并设置indicator=True

In [80]:
df1 = pd.DataFrame(  
"City" : ["Chicago", "San Franciso", "Boston"] , 
"State" : ["Illinois", "California", "Massachusett"]  )
​
df2 = pd.DataFrame(  
"City" : ["Chicago",  "Mmmmiami", "Dallas" , "Omaha"] , 
"State" : ["Illinois", "Florida", "Texas", "Nebraska"]  )
pd.merge(df1,df2, how='outer', indicator=True)

Out[80]:
           City         State      _merge
0       Chicago      Illinois        both
1  San Franciso    California   left_only
2        Boston  Massachusett   left_only
3      Mmmmiami       Florida  right_only
4        Dallas         Texas  right_only
5         Omaha      Nebraska  right_only

这会添加一列来指示行是否仅存在于 lhs 或 rhs 中

【讨论】:

【参考方案2】:

如果你在使用 pandas

你可以像这样工作自己的方式

In [182]: df = pd.merge(df1, df2, on='City', how='outer')

In [183]: df
Out[183]:
           City       State_x   State_y
0       Chicago      Illinois  Illinois
1  San Franciso    California       NaN
2        Boston  Massachusett       NaN
3      Mmmmiami           NaN   Florida
4        Dallas           NaN     Texas
5         Omaha           NaN  Nebraska

In [184]: df.ix[df['State_y'].isnull(),:]
Out[184]:
           City       State_x State_y
1  San Franciso    California     NaN
2        Boston  Massachusett     NaN

【讨论】:

【参考方案3】:

基于@EdChum 的建议:

df = pd.merge(df1, df2, how='outer', suffixes=('','_y'), indicator=True)
rows_in_df1_not_in_df2 = df[df['_merge']=='left_only'][df1.columns]

rows_in_df1_not_in_df2

|Index |City        |State       |
|------|------------|------------|
|1     |San Franciso|California  |
|2     |Boston      |Massachusett|

编辑:合并@RobertPeters 的建议

【讨论】:

应该是df = pd.merge(df1, df2, how='outer', suffixes = ('','_y') ,indicator=True)才能工作【参考方案4】:

您还可以使用列表推导式并比较行以返回缺失的元素:

dif_list = [x for x in list(df1['City'].unique()) if x not in list(df2['City'].unique())]

返回:

['San Franciso', 'Boston']

然后你可以得到一个只有不同行的数据框:

dfdif = df1[(df1['City'].isin(dif_list))]

【讨论】:

以上是关于比较 PandaS DataFrames 并返回第一个缺失的行的主要内容,如果未能解决你的问题,请参考以下文章

比较 Python Pandas DataFrames 以匹配行

具有 NaN 相等性比较的 Pandas DataFrames

使用多处理时结合 Pandas DataFrames

使用 List Comprehension (Pandas) 从 DataFrames 列表中删除 DataFrames 列

Pandas文摘:Applying Operations Over pandas Dataframes

python Pandas - 过滤DataFrames和Series