Сравнить 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 таблицы:
и
нужно получить:
Файлы располагаются по ссылкам:
Ответы (2 шт):
Ну вот смотрите: судя по вашим файлам, первый значимый уникальный столбец у вас будет идти под номером 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 нд нд нд нд нд нд нд нд нд нд нд нд нд нд нд нд нд нд
===
и уже со значениями в этих строках можете работать.
Однако, нужно иметь в виду, что здесь еще не учитывается вариант, когда количество строк во фреймах не совпадает.
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, как в первоначальном файле