【问题标题】:How to compare a pandas dataframe with an updated version of it?如何将 pandas 数据框与其更新版本进行比较?
【发布时间】:2019-09-26 09:43:30
【问题描述】:

我有一个数据框和同一数据框的更新版本,其中第 1 行中的颜色已更改,第 2 行已删除并附加了一行。

我想将具有新 ID 的行附加到旧数据框,然后比较两个数据框并写入比较结果(例如“新条目”、“更新颜色”、“条目已删除”或“无更改” ) 到“比较”列中。

   Name  Colour      ID Compare
0  Lisa     Red   Apple        
1  Anna    Blue  Banana        
2  Anna  Yellow  Orange        
3   Max   Green    Pear   


    Name  Colour      ID
0   Lisa  Purple   Apple
1   Anna  Yellow  Orange
2  Peter    Pink   Grape

我尝试了几种使用 .iloc 和 .where 的方法,但是我对选择/操作缺乏经验,所以没有成功。这是我想要实现的目标:

   Name  Colour      ID         Compare
0  Lisa     Red   Apple  Colour changed
1  Anna    Blue  Banana   Entry deleted
2  Anna  Yellow  Orange      No changes
3   Max   Green    Pear       New entry

感谢您的帮助。

这是为了创建数据框:

import pandas as pd

data = {'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)] = newrow
updatedDf = updatedDf.reset_index(drop=True)

【问题讨论】:

标签: python pandas


【解决方案1】:

您可以创建一个新旧版本的 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_updatedColour_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'

虽然有点复杂,但在最后 4 个语句中检查所有条目是否为NaN 是必要的。与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-01-17
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    相关资源
    最近更新 更多