Сравнить 2 Excel файла с одинаковым количеством столбцов, но разным количеством строк

Есть 2 файла. Их нужно сравнить. Известно, что строки могут меняться местами, количество строк может увеличиваться (могут появляться новые позиции). Нужно подсвечивать/выводить те значения, которые поменялись. Желательно старые значения тоже выводить. Я пробовала так:

import pandas as pd

df1 = pd.read_excel('1.xlsx')
df2 = pd.read_excel('2.xlsx')
df1 = df1[15:]

df1['Unnamed: 1'].loc[15]='Index'
for n in range(4, df1.shape[1],2):
    df1['Unnamed: %s'%n].loc[15]=df1['Unnamed: %s'%(n-1)].loc[15]
df1.columns = df1.loc[15:16].fillna('').apply(' '.join).str.strip()
df1 = df1[2:]

df1.reset_index(drop=True).head()
#df1 = df1.set_index('Index')

df2 = df2[15:]
df2['Unnamed: 1'].loc[15]='Index'
for n in range(4, df2.shape[1],2):
    df2['Unnamed: %s'%n].loc[15]=df2['Unnamed: %s'%(n-1)].loc[15]
df2.columns = df2.loc[15:16].fillna('').apply(' '.join).str.strip()
df2 = df2[2:]

df2.reset_index(drop=True).head()
#df2 = df2.set_index('Index') 
difference = df2[df1!=df2]

difference.fillna(' ') 

Если я устанавливаю индексом столбец "Index" , то программа ломается при замене местами строк и вообще не работате, когда я добавляю новые строки. Если же я не устанавлиываю столбец "Index" , то при смене строк местами она подсвечивает все две строки. То есть, предположим, что есть 2 таблицы: введите сюда описание изображения и введите сюда описание изображения нужно получить: введите сюда описание изображения Файлы располагаются по ссылкам:

файл1

файл2


Ответы (2 шт):

Автор решения: strawdog

Ну вот смотрите: судя по вашим файлам, первый значимый уникальный столбец у вас будет идти под номером 2 - его и нужно делать индексом. Затем сравнивать по строками датафреймы - вы увидите строки, которые не совпадают. Например, так:

import pandas as pd

df1 = pd.read_excel('1.xlsx', skiprows=18)
df2 = pd.read_excel('2.xlsx', skiprows=18)
df1=df1.set_index(2)
df2=df2.set_index(2)

for i in df1.index:
    if not (df1.loc[i].equals(df2.loc[i])):
        print(f"df1:{df1.loc[[i]]}, \ndf2{df2.loc[[i]]}")
        print("===")

вы получите попарно несовпадающие строки из обоих фреймов:

df1:                                                 1  3    4.1    4.2     4.3     4.4   4.5    4.6     4.7      4.8 5.1   5.2 5.3 5.4 6.1     6.2 6.3   6.4 6.5 6.6 7.1 7.2   8.1   8.2     9.1    9.2     9.3     9.4
2                                                                                                                                                                                                                   
ВСЕГО по инвестиционной программе, в том числе:  0  Г  48.48  57.94  418.89  488.76  49.7  60.58  108.89  163.535  нд  42.6  нд  18  нд  1.2754  нд  0.55  нд  нд  нд  нд  4.94  3.27  305.23  163.4  367.39  341.17, 
df2                                                 1  3    4.1    4.2     4.3     4.4   4.5    4.6     4.7      4.8 5.1   5.2 5.3 5.4 6.1     6.2 6.3   6.4 6.5 6.6 7.1 7.2   8.1   8.2     9.1    9.2     9.3     9.4
2                                                                                                                                                                                                                   
ВСЕГО по инвестиционной программе, в том числе:  0  Г  50.14  57.94  418.89  488.76  49.7  60.58  108.89  163.535  нд  42.6  нд  18  нд  1.2754  нд  0.55  нд  нд  нд  нд  4.94  3.27  305.23  163.4  367.39  341.17
===
df1:                                        1  3    4.1   4.2    4.3   4.4   4.5    4.6     4.7      4.8 5.1 5.2 5.3 5.4 6.1 6.2 6.3 6.4 6.5 6.6 7.1 7.2 8.1 8.2 9.1 9.2 9.3 9.4
2                                                                                                                                                                           
Технологическое присоединение, всего  0.1  Г  44.36  48.4  12.57  0.16  40.1  49.73  108.89  138.245  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд, 
df2                                        1  3    4.1   4.2    4.3   4.4   4.5    4.6     4.7      4.8 5.1 5.2 5.3 5.4 6.1 6.2 6.3 6.4 6.5 6.6 7.1 7.2 8.1 8.2 9.1 9.2 9.3 9.4
2                                                                                                                                                                           
Технологическое присоединение, всего  0.1  Г  47.38  48.4  12.57  0.16  40.1  49.73  108.89  138.245  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд  нд
===

и уже со значениями в этих строках можете работать.

Однако, нужно иметь в виду, что здесь еще не учитывается вариант, когда количество строк во фреймах не совпадает.

→ Ссылка
Автор решения: Elena Barbanova
import pandas as pd
import numpy as np

df1 = pd.read_excel('1.xlsx')
df2 = pd.read_excel('2.xlsx')
df1 = df1[15:]




df1['Unnamed: 1'].loc[15]='Index'
df1['Unnamed: 2'].loc[15]='Index 2'
df1['Unnamed: 0'].loc[15]='Index 3'
for n in range(4, df1.shape[1],2):
    df1['Unnamed: %s'%n].loc[15]=df1['Unnamed: %s'%(n-1)].loc[15]
df1.columns = df1.loc[15:16].fillna('').apply(' '.join).str.strip()
df1 = df1[2:]

df1.reset_index(drop=True).head()
df1 = df1.set_index('Index')




df2 = df2[15:]
df2['Unnamed: 1'].loc[15]='Index'
df2['Unnamed: 2'].loc[15]='Index 2'
df2['Unnamed: 0'].loc[15]='Index 3'
for n in range(4, df2.shape[1],2):
    df2['Unnamed: %s'%n].loc[15]=df2['Unnamed: %s'%(n-1)].loc[15]
df2.columns = df2.loc[15:16].fillna('').apply(' '.join).str.strip()
df2 = df2[2:]


df2.reset_index(drop=True).head()
df2 = df2.set_index('Index')

for ind in df2.index:
    if ind not in df1.index:
        df1.loc[ind] = [np.nan] * df1.shape[1]
    

df1.to_excel('1a.xlsx')
df2.to_excel('2a.xlsx')


df1 = pd.read_excel('1a.xlsx')
df2 = pd.read_excel('2a.xlsx')

df1 = df1.drop([0])
df2 = df2.drop([0])

df0 = df2.set_index('Index')

df1 = df1.sort_values(['Index'])
df1 = df1.set_index('Index')


df2 = df2.sort_values(by=['Index'])
df2 = df2.set_index('Index')

df_all = pd.concat([df1, df2],axis='columns', keys=['First', 'Second'], sort=False)
df_final = df_all.swaplevel(axis='columns')[df1.columns[1:]]

# df_final = df_final.reindex(df0.index)
# df_final = df_final.reindex(list(df0.index))
df_final = df_final.reset_index()

# df_final = df_final.sort_values(by = 'Index', key = df0.index)

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['tosort'] = df0.index
# df_final = df_final.sort_values('tosort')

df_final = df_final.style.apply(highlight_diff, axis=None)
# df_final = df_final.set_index("Index")
# df_final = df_final.reindex(df0.index)
df_final


 

Осталась одна проблемка - отсортировать фрейм по столбцу Index, как в первоначальном файле

→ Ссылка