【问题标题】:How to highlight differences in pandas data frame after concatenating them?连接后如何突出熊猫数据框的差异?
【发布时间】:2019-02-26 05:59:45
【问题描述】:

我有两个数据框如下:

XYZ
Year Quantity Car     Colour
2001 1000     Swift   Red
2001 16       Wagonar White
2001 16       Wagonar Black
2001 200      Baleno  Silver
2001 20       Zen     White

ABC  
Year Quantity Car     Colour
2001 1000     Swift   Red
2001 16       Wagonar White
2001 200      Baleno  Silver
2001 44       Alto    Blue

输出应该是这样的:

Year      Quantity Car             Colour
XYZ  ABC  XYZ  ABC XYZ     ABC     XYZ    ABC
2001 2001 1000 100 Swift   Swift   Red    Red
2001 2001 16   16  Wagonar Wagonar White  White
2001 2001 16       Wagonar         Black 
2001 2001 200  200 Baleno  Baleno  Silver Silver
2001 2001 20       Zen             White
2001 2001      44          Alto           Blue

我试过了

df_all = pd.concat([df_temp, df_temp1], axis='columns', keys=['XYZ', 'ABC'])
print(df_all)
df_final = df_all.swaplevel(axis='columns')[df_temp.columns]
print(df_final)
def highlight_diff(data, color='yellow'):
    attr = 'background-color: {}'.format(color)
    other = data.xs('First', axis='columns', level=-1)
    return pd.DataFrame(np.where(data.ne(other, level=0), attr,''),index=data.index, columns=data.columns)

 df_final.style.apply(highlight_diff, axis=None)
 print(df_final)

应突出显示数据框之间的差异。

例如,在这种情况下,必须突出显示 Cars: Wagonar Zen 和 Alto,因为它们在两个数据帧中是不同的

我尝试了这种连接方式:

    YEAR Quantity  CAR    COLOR  car     color
0   2001    16    Wagonar white  Wagonar white
1   2001    16    Wagonar black  Wagonar white
2   2001    20    Zen     white  NaN     NaN
3   2001    44    NaN     NaN    Alto    blue
4   2001   200    Baleno  silver Baleno  silver
5   2001  1000    Swift   red    Swift   red

所有大写标题属于 xyz 公司,小标题属于 abc 我们如何将“CAR”列与“car”列以及“COLOR”列与“color”列进行比较,并突出显示值不匹配的整行。

我试过了:

def highlight_rows(s):        
if not (s['CAR'] == s['car'] and s['COLOR'] == s['color']):
    return 'background-color: green'

df_final.style.apply(highlight_rows, axis = None)

但这不起作用

【问题讨论】:

    标签: python python-3.x pandas dataframe


    【解决方案1】:

    重复对 Year 和 Quantity 存在问题,因此可能的解决方案是在 concat 之前使用计数器创建唯一的 MultiIndex:

    df_temp.index = df_temp.groupby(['Year','Quantity']).cumcount()
    df_temp1.index = df_temp1.groupby(['Year','Quantity']).cumcount()
    
    df_all = (pd.concat([df_temp.set_index(['Year','Quantity'], append=True), 
                         df_temp1.set_index(['Year','Quantity'], append=True)], 
                         axis='columns', 
                         keys=['XYZ', 'ABC']))
    print(df_all)
                         XYZ              ABC        
                         Car  Colour      Car  Colour
      Year Quantity                                  
    0 2001 16        Wagonar   White  Wagonar   White
           20            Zen   White      NaN     NaN
           44            NaN     NaN     Alto    Blue
           200        Baleno  Silver   Baleno  Silver
           1000        Swift     Red    Swift     Red
    1 2001 16        Wagonar   Black      NaN     NaN
    

    然后将index 转换为DataFrame 和concat 再次转换为MultiIndex:

    df = df_all.index.to_frame().drop(0, axis=1)
    df1 = pd.concat([df, df], axis=1, keys=('XYZ','ABC'))
    print (df1)
                      XYZ            ABC         
                     Year Quantity  Year Quantity
      Year Quantity                              
    0 2001 16        2001       16  2001       16
           20        2001       20  2001       20
           44        2001       44  2001       44
           200       2001      200  2001      200
           1000      2001     1000  2001     1000
    1 2001 16        2001       16  2001       16
    
    df_final = df_all.join(df1).reset_index(drop=True).swaplevel(axis='columns')[df_temp.columns]
    print(df_final)
       Year       Quantity            Car           Colour        
        XYZ   ABC      XYZ   ABC      XYZ      ABC     XYZ     ABC
    0  2001  2001       16    16  Wagonar  Wagonar   White   White
    1  2001  2001       20    20      Zen      NaN   White     NaN
    2  2001  2001       44    44      NaN     Alto     NaN    Blue
    3  2001  2001      200   200   Baleno   Baleno  Silver  Silver
    4  2001  2001     1000  1000    Swift    Swift     Red     Red
    5  2001  2001       16    16  Wagonar      NaN   Black     NaN
    

    最后添加新掩码并按位组合 - |:

    def highlight_diff(data, color='yellow'):
        attr = 'background-color: {}'.format(color)
        other1 = data.xs('XYZ', axis='columns', level=-1)
        other2 = data.xs('ABC', axis='columns', level=-1)
        return pd.DataFrame(np.where(data.ne(other1, level=0) | 
                                     data.ne(other2, level=0), attr,''),
                            index=data.index, columns=data.columns)
    

    df_final = pd.DataFrame({('Year', 'XYZ'): {0: 2001, 1: 2001, 2: 2001, 3: 2001, 4: 2001, 5: 2001}, ('Year', 'ABC'): {0: 2001, 1: 2001, 2: 2001, 3: 2001, 4: 2001, 5: 2001}, ('Quantity', 'XYZ'): {0: 16, 1: 20, 2: 44, 3: 200, 4: 1000, 5: 16}, ('Quantity', 'ABC'): {0: 16, 1: 20, 2: 44, 3: 200, 4: 1000, 5: 16}, ('Car', 'XYZ'): {0: 'Wagonar', 1: 'Zen', 2: np.nan, 3: 'Baleno', 4: 'Swift', 5: 'Wagonar'}, ('Car', 'ABC'): {0: 'Wagonar', 1: np.nan, 2: 'Alto', 3: 'Baleno', 4: 'Swift', 5: np.nan}, ('Colour', 'XYZ'): {0: 'White', 1: 'White', 2: np.nan, 3: 'Silver', 4: 'Red', 5: 'Black'}, ('Colour', 'ABC'): {0: 'White', 1: np.nan, 2: 'Blue', 3: 'Silver', 4: 'Red', 5: np.nan}})
    

    【讨论】:

    • 仍然无法正常工作,我没有正确合并我的代码,我需要帮助
    • @Miffy - 看起来更复杂,但现在可以工作了。请检查一下。
    • 两辆旅行车应该放在一起,整个汽车应该突出显示,而不仅仅是白色
    • @Miffy - entire car should be highlighted not just the white colour - 你能解释更多吗?
    • 首先我们检查 xyz 和 abc 两家公司的生产数量。 xyz 公司在这里生产 16 辆白色和 16 辆黑色货车,而 abc 公司只生产 16 辆白色货车。因此,wagonar 汽车的制造存在差异,因此需要突出显示汽车名称为 wagonar 的两行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2016-03-09
    • 2013-11-23
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多