在两个数据帧中查找已更改的行(行的子集)



>我每天收到 2 个包含 2 列的 csv 文件。一个具有唯一标识符,另一个具有值。我正在尝试比较每个标识符的值并保留值已更改的那些行。

Id1        Value_today
abc        500
def        600
ghi        700
jkl        800

Id1        Value_Yesterday
abc        500
def        650
ghi        750
jkl        800
mno        900

所需的输出将是

Id1        Value
def        650
ghi        750
mno        900

到目前为止,我已经尝试过:

df4 = df1.merge(df2,how='outer',on='Id1')
df4['check']=df4.Value_today==df4.Value_Yesterday
df4 = df4[df4['check'] == False]

但这会返回一个空数据帧。 我做错了什么吗?

我会这样做:

In [11]: d1
Out[11]:
   Id1  Value
0  abc    500
1  def    600
2  ghi    700
3  jkl    800
In [12]: d2
Out[12]:
   Id1  Value
0  abc    500
1  def    650
2  ghi    750
3  jkl    800
4  mno    900
In [13]: %paste
r = pd.concat([d1.assign(x='old'), d2.assign(x='new')], ignore_index=True) 
      .drop_duplicates(subset=['Id1','Value'], keep=False) 
      .set_index(['Id1','x']) 
      .unstack() 
      .reset_index()
r.columns = [col[1] if col[1] else col[0] for col in r.columns]
## -- End pasted text --

结果:

In [16]: r
Out[16]:
   Id1    new    old
0  def  650.0  600.0
1  ghi  750.0  700.0
2  mno  900.0    NaN
In [17]: r[['Id1','old','new']]
Out[17]:
   Id1    old    new
0  def  600.0  650.0
1  ghi  700.0  750.0
2  mno    NaN  900.0

更通用的情况(具有多列):

In [27]: d1
Out[27]:
   ID  a  b  c
0   1  1  2  3
1   2  4  5  6
2   3  7  8  9
In [28]: d2
Out[28]:
   ID  a  b   c
0   1  1  2   3
1   2  4  0   6
2   3  7  8  10
3   4  1  1   1
In [29]: %paste
r = pd.concat([d1.assign(x='old'), d2.assign(x='new')], ignore_index=True) 
      .drop_duplicates(subset=d1.columns.tolist(), keep=False) 
      .set_index(['ID','x']) 
      .unstack() 
      .reset_index()
## -- End pasted text --
In [30]: r
Out[30]:
  ID    a         b          c
x     new  old  new  old   new  old
0  2  4.0  4.0  0.0  5.0   6.0  6.0
1  3  7.0  7.0  8.0  8.0  10.0  9.0
2  4  1.0  NaN  1.0  NaN   1.0  NaN

这段代码应该适用于任意数量的列,它将保留old_df中尚不存在的new_df中的每一行,即只有新的和更改的行

注意:代码假定两个数据帧中的列计数和列名完全相同。

def filter_new_and_changed_rows(new_df, old_df):
    old_indexes = pd.MultiIndex.from_arrays([old_df[col] for col in old_df.columns])
    new_indexes = pd.MultiIndex.from_arrays([new_df[col] for col in new_df.columns])
    changed_df = new_df.loc[~new_indexes.isin(old_indexes)]
    return changed_df

相关内容

  • 没有找到相关文章

最新更新