pandas Python:基于主键比较相邻列

ghg1uchk  于 2023-05-27  发布在  Python
关注(0)|答案(2)|浏览(140)

请参考此链接查看数据pandas合并两个dataframe并按相邻列中的比较列进行排序
如何根据主键(这里是ID 1和ID 2)比较相邻列,例如:Lang_1与Lang_2,Mat_1与Mat_2等等,如果发现该特定行的任何不匹配B/w相邻列,则状态应失败,如果所有相邻列都匹配,则通过我如何做到这一点。谁能帮帮我。

import pandas as pd

exam_1 = {
  'ID1': ['1', '2', '3', '3', '5', '5'],
  'ID2': ['1', '1', '4', '5', '1', '2'],
  'Mat': [80, 75, 50, 93, 88, 90],
  'Science': [96, 97, 99, 87, 90, 88],
}

exam_2 = {
  'ID1': ['1', '2', '3', '3', '5'],
  'ID2': ['1', '1', '4', '5', '1'],
  'Mat': [80, np.nan , 50, 93, 88],
  'Science': [50, 60, 85, 90, 66],
}
df_1 = pd.DataFrame(exam_1)
df_2 = pd.DataFrame(exam_2)

cmp =  pd.merge(df_1, df_2, how="outer", on=['ID1','Id2'], suffixes=("_1", "_2"))
            .set_index('ID1','ID2')
            .sort_index(axis=1)
            .reset_index()

cmp['Status'] = cmp.iloc[:, 2:].apply(lambda x: 'Pass' if x[0]==x[1] else 'Fail', axis =1)

下面我将介绍两种情况
1.如果df 2中存在df 1的主键a)如果两个相邻单元格匹配,则应使用绿色突出显示b)如果两个相邻单元格不匹配,则应使用红色突出显示c)如果任何单元格为空白,则应使用黄色突出显示
1.如果df 1的主键不存在于df 2中,则除主键外,整行应以黄色突出显示。

z9zf31ra

z9zf31ra1#

修改代码:

import pandas as pd

exam_1 = {
  'ID1': [1, 2, 3, 4, 5, 6],
  'ID2': [1, 2, 3, 4, 5, 6],
  'Mat': [85, 75, 50, 93, 88, 90],
  'Science': [96, 97, 99, 87, 90, 88],
  'Reading': [80, 60, 72, 86, 84, 77],
  'Writing': [78, 82, 88, 78, 86, 82],
  'Lang': [77, 79, 77, 72, 90, 92],
}

exam_2 = {
  'ID1': [1, 2, 3, 4, 5, 6],
  'ID2': [1, 2, 3, 4, 5, 6],
  'Mat': [80, 80, 90, 90, 85, 80],
  'Science': [50, 60, 85, 90, 66, 82],
  'Reading': [60, 75, 55, 90, 85, 60],
  'Writing': [56, 66, 90, 82, 60, 80],
  'Lang': [80, 78, 76, 90, 77, 66],
}

df_1 = pd.DataFrame(exam_1)
df_2 = pd.DataFrame(exam_2)

cmp = pd.merge(df_1, df_2, how="outer", on=['ID1', 'ID2'], suffixes=("_1", "_2")) \
    .set_index(['ID1', 'ID2']) \
    .sort_index(axis=1) \
    .reset_index()

cmp['Status'] = cmp.iloc[:, 3:].apply(lambda x: 'Pass' if x[0] == x[1] else 'Fail', axis=1)

以下是变化:
1.将'ID1''ID2'添加到检查数据字典中,以匹配合并操作中的列名。
1.修复了列名'Writing'中的拼写错误。
1.将'ID1''ID2'添加到set_index函数中,以设置DataFrame的索引。
1.已将apply函数中的iloc索引调整为从第三列(iloc[:, 3:])开始,以排除不可比较的列。
1.修改了lambda函数,如果相邻值相等(x[0] == x[1]),则返回'Pass',否则返回'Fail'
在这些更改之后,cmp DataFrame将包含列ID1ID2以及来自df_1df_2的原始列。Status列将指示每行中的相邻值是否匹配。

ozxc1zmp

ozxc1zmp2#

IIUC,您可以用途:

cmp =  (
    pd.merge(df_1, df_2, how="outer", on=["ID1", "ID2"], suffixes=("_1", "_2"))
        .set_index(["ID1", "ID2"]).sort_index(axis=1)
)
            
cmp["Status"] = (
    np.where(
        (cmp.filter(like="_1").to_numpy() == cmp.filter(like="_2").to_numpy())
            .all(axis=1), "Pass", "Fail")
)

#or, use your approach
#cmp["Status"] = cmp.apply(lambda x: "Pass" if x[0]==x[1] else "Fail", axis=1)

cmp = cmp.reset_index()

输出:

print(cmp)

  ID1 ID2  Lang_1  Lang_2  ...  Science_2  Wiritng_1  Wiritng_2  Status
0   1   1      77      80  ...         50         78         56    Fail
1   2   1      79      78  ...         60         82         66    Fail
2   3   4      77      76  ...         85         88         90    Fail
3   3   5      72      90  ...         90         78         82    Fail
4   5   1      90      77  ...         66         86         60    Fail
5   5   2      92      66  ...         82         82         80    Fail

更新:

  • 以下是我想介绍的两个场景:*

如果df1的主键存在于df2中

  • a)如果两个相邻单元格都匹配,则应该用绿色突出显示
  • B)如果两个相邻单元格不匹配,则应使用红色突出显示
  • c)如果任何单元格为空白,则为黄色

如果df1的主键不存在于df2中:

  • 除主键外,整行应使用黄色突出显示。
cmp =  (
    pd.merge(df_1, df_2, how="outer", on=["ID1", "ID2"],
             suffixes=("_1", "_2"), indicator=True)
        .set_index(["ID1", "ID2"]).sort_index(axis=1).reset_index()
)

is_match = cmp.pop("_merge").eq("both")

def color_match(df):
    tmp = df.set_index(["ID1", "ID2"]).reset_index(drop=True)
    l = tmp.eq(tmp.shift(-1, axis=1)).mul(is_match, axis=0)
    r = tmp.eq(tmp.shift(+1, axis=1)).mul(is_match, axis=0)
    
    pairs = l.add(r).replace(
        {True: "background-color: lightgreen",
         False: "background-color: lightcoral"})
        
    ids = pd.DataFrame(
        "", columns=cmp[["ID1", "ID2"]].columns,
        index=cmp[["ID1", "ID2"]].index)

    return pd.concat([ids, pairs], axis=1)

def color_diff(_):
    return np.where(~is_match, "background-color: yellow", "")

pd.set_option("styler.format.precision", 0)
(
    cmp.style.apply(color_match, axis=None)
     .apply(color_diff, axis=0, subset=cmp.iloc[:, 2:].columns)
     .highlight_null(color="yellow")
     # .to_excel("output.xlsx", index=False) #uncomment to make a spreadsheet
)

相关问题