сравнить dfs, которые не имеют уникального значения

#python #pandas #dataframe

#python #панды #фрейм данных

Вопрос:

 df1:

 Parameters TrueResult     
 Defaults    authenticate  
 xyz         ALL             

df2:  
Parameters   ConfigResult       
 Defaults    authenticate     
  xyz        noone            
  

У меня есть 2 фрейма данных. Я создал их из 2 разных текстовых файлов.
Случай:
Я буду сравнивать конфигурацию файла с истинными результатами.
df1 имеет истинные результаты для заданных параметров.
df2 имеет конфигурации данного файла.

 Expected Output:

 Parameters TrueResult      ConfigResult     AuditResult
 Defaults    authenticate    authenticate     ok
 xyz         ALL             noone            analyze
  

Комментарии:

1. Каков ваш ожидаемый результат?

2. Привет, я добавил ожидаемый результат.

Ответ №1:

Вы можете сделать следующее:

 In [1054]: import numpy as np

In [1055]: res = pd.concat([df1.set_index('Parameters'),df2.set_index('Parameters')],axis=1).reset_index()

In [1058]: res['AuditResult'] = np.where(res.TrueResult.eq(res.ConfigResult), 'ok', 'analyze')

In [1059]: res
Out[1059]: 
  Parameters    TrueResult   ConfigResult AuditResult
0   Defaults      envreset      !envreset     analyze
1   Defaults  mail_badpass  !mail_badpass     analyze
2   Defaults  authenticate   authenticate          ok
3        xyz           ALL          noone     analyze
  

Комментарии:

1. я думаю, это нормально, но когда я применил поле результатов аудита, оно заполнено анализом, я пытаюсь понять

2. Да, логика AuditResult заключается в том, что If TrueResult соответствует ConfigResult then ok , в противном analyze случае . Разве это не правильная логика? Дайте мне знать, если есть что-то еще.

3. да, это так, но когда я применил код, я получаю только анализ, даже если данные одинаковы 🙂

4. Это странно. Единственное объяснение заключается в том, что ваши данные имеют whitespaces , поэтому они не выполняют точное совпадение строк. Вы можете это проверить?

5. Да, столбец df2 ConfigResult имеет пробелы в конце каждой строки

Ответ №2:

Вот одно из возможных решений. Вы можете сначала concat создать фреймы данных, а затем использовать apply :

  • pd.concat:
 >>> df_merged = pd.concat([df1.set_index('Parameters'),df2.set_index('Parameters')],axis=1).reset_index()

##df_merged
  Parameters    TrueResult   ConfigResult
0   Defaults      envreset      !envreset
1   Defaults  mail_badpass  !mail_badpass
2   Defaults  authenticate   authenticate
3        xyz           ALL          noone
  
  • apply :
 >>> d = {True:'analyze', False:'ok'}
>>> df_merged['AuditResult'] = df_merged.apply(lambda x : x['TrueResult']!=x['ConfigResult'],axis=1 ).map(d)
  

Вывод:

   Parameters    TrueResult   ConfigResult AuditResult
0   Defaults      envreset      !envreset     analyze
1   Defaults  mail_badpass  !mail_badpass     analyze
2   Defaults  authenticate   authenticate          ok
3        xyz           ALL          noone     analyze
  

Комментарии:

1. Я не думаю, что ваш вывод соответствует выводу, который требуется OP.

2. @MayankPorwal В чем проблема с моим ответом / выводом. Я не мог понять.

3. @MayankPorwal Хорошо. Большое спасибо. Возможно pd.concat , с parameters индексом as. Он работал с pd.read_clipboard()

4. apply как правило, медленнее. Вы можете проверить мой ответ, который использует numpy.where .

5. Конечно. Мне тоже не понравилось apply решение. np.where / assign — лучший способ пойти.

Ответ №3:

Сначала объедините 2 dfs, затем используйте функцию assign для анализа двух столбцов и создания третьего столбца:

 df = pd.concat([
     df1.assign(Parameters = lambda x: x['Parameters'].str.strip()),
     df2.assign(Parameters = lambda x: x['Parameters'].str.strip())
], axis=1).assign(AuditResult= lambda x: np.where(x['TrueResult'] == x['ConfigResult'],"OK","analyze"))
  

Комментарии:

1. Возможно, вам нужна очистка пространства для значений ваших параметров. Я обновился, чтобы выполнить обрезку значений ваших параметров

2. df.assign это хороший подход. Добавлены недостающие кавычки X[configResult] в вашем ответе.