为了账号安全,请及时绑定邮箱和手机立即绑定

如何将 pandas 数据框与其更新版本进行比较?

如何将 pandas 数据框与其更新版本进行比较?

沧海一幻觉 2022-06-07 17:54:32
我有一个数据框和同一数据框的更新版本,第 1 行中的颜色已更改,第 2 行已删除并附加了一行。我想将具有新 ID 的行附加到旧数据框,然后比较两个数据框并将比较结果(例如“新条目”、“更新颜色”、“条目删除”或“无更改”)写入“比较”栏。   Name  Colour      ID Compare0  Lisa     Red   Apple        1  Anna    Blue  Banana        2  Anna  Yellow  Orange        3   Max   Green    Pear       Name  Colour      ID0   Lisa  Purple   Apple1   Anna  Yellow  Orange2  Peter    Pink   Grape我已经尝试了几种使用 .iloc 和 .where 的方法,但是我对选择/操作太缺乏经验,所以没有成功。这是我想要实现的目标:   Name  Colour      ID         Compare0  Lisa     Red   Apple  Colour changed1  Anna    Blue  Banana   Entry deleted2  Anna  Yellow  Orange      No changes3   Max   Green    Pear       New entry我很感激任何帮助。这是为了创建数据框:import pandas as pddata = {'Name': ['Lisa', 'Anna', 'Anna', 'Max'],        'Colour': ['Red', 'Blue', 'Yellow', 'Green'],        'ID': ['Apple', 'Banana', 'Orange', 'Pear'],        'Compare': ['','','','']}df = pd.DataFrame(data, columns = ['Name', 'Colour', 'ID', 'Compare'])updatedDf = df.copy()updatedDf = updatedDf.iloc[:, :-1]updatedDf.set_value(0, 'Colour', 'Purple')updatedDf = updatedDf.drop(1)newrow = ['Peter', 'Pink', 'Grape']updatedDf.loc[len(updatedDf)] = newrowupdatedDf = updatedDf.reset_index(drop=True)
查看完整描述

1 回答

?
Qyouu

TA贡献1786条经验 获得超11个赞

您可以使用外部连接并排创建具有旧版本和新版本的 DataFrame


>> df2 = pd.merge(df, updatedDf, on ='ID', how='outer', suffixes=['', '_update'])

   Name  Colour      ID Compare Name_update Colour_update

0  Lisa     Red   Apple                Lisa        Purple

1  Anna    Blue  Banana                 NaN           NaN

2  Anna  Yellow  Orange                Anna        Yellow

3   Max   Green    Pear                 NaN           NaN

4   NaN     NaN   Grape     NaN       Peter          Pink

现在您需要定义如何识别每个案例:

  1. 如果NameColour是 NaN,则条目是新的

  2. 如果Name_updated并且Colour_updated是 NaN 则条目被删除

  3. 如果NameColour都等于Name_updatedColour_updated,则条目未更改

  4. 如果NameName_updated相等但ColorColour_updated不相等,则颜色已更改

  5. 如果名称更改,反之亦然

  6. 如果NameColour不等于Name_updatedColour_updated,您还没有定义预期的行为

请注意,这不会处理边缘情况,例如仅删除一个字段或 ID 不唯一时

您可以将所有条件封装到一个函数中并使用 apply 或者像这样通过复制粘贴来完成

df2.loc[df2[['Name', 'Colour']].isnull().any(axis=1), 'Compare'] = 'New entry'

df2.loc[df2[['Name_updated', 'Colour_updated']].isnull().any(axis=1), 'Compare'] = 'Entry deleted'

df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] == df2['Name_updated']) & (df2['Colour'] == df2['Colour_updated']), 'Compare'] = 'No changes'

df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] == df2['Name_updated']) & (df2['Colour'] != df2['Colour_updated']), 'Compare'] = 'Colour changed'

df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] != df2['Name_updated']) & (df2['Colour'] == df2['Colour_updated']), 'Compare'] = 'Name changed'

df2.loc[(~df2[['Name', 'Colour', 'Name_updated', 'Colour_updated']].isnull().any(axis=1)) & (df2['Name'] != df2['Name_updated']) & (df2['Colour'] != df2['Colour_updated']), 'Compare'] = 'Name and colour changed'

虽然有点复杂,但NaN在最后 4 个语句中检查是否没有任何条目是必要的。比较NaN总是正确的,所以这种方式更安全一些。


尽可能采用新价值观


df2['Name'].update(df2['Name_updated'])                                                                                                                                                                   

df2['Colour'].update(df2['Colour_updated'])

此处使用的 Series.update 方法会跳过自动删除值的行。


最后,您可能会丢弃临时列。


df2.drop(['Name_updated', 'Colour_updated'], axis=1, inplace=True)                                                                                                                                                      


    Name  Colour      ID         Compare

0   Lisa  Purple   Apple  Colour changed

1   Anna    Blue  Banana   Entry deleted

2   Anna  Yellow  Orange      No changes

3    Max   Green    Pear   Entry deleted

4  Peter    Pink   Grape       New entry


查看完整回答
反对 回复 2022-06-07
  • 1 回答
  • 0 关注
  • 161 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信