Как сравнить два столбца для сопоставления и несоответствия значений и получить его в нужном формате? - PullRequest
0 голосов
/ 26 марта 2019

Как найти совпадающие и не совпадающие значения между двумя столбцами и отформатировать их следующим образом?

Введите:

| expected | match | forward | backward | actual |
|----------|-------|---------|----------|--------|
| a        |       |         |          | b      |
| b        |       |         |          | c      |
| c        |       |         |          | r      |
| d        |       |         |          | s      |
| e        |       |         |          |        |

Выход:

| expected | match | forward | backward | actual |
|----------|-------|---------|----------|--------|
| a        | b     | a       | r        | b      |
| b        | c     | d       | s        | c      |
| c        |       | e       |          | r      |
| d        |       |         |          | s      |
| e        |       |         |          |        |

forward - присутствует в expected, но не в actual (SQL left outer join)

backward - присутствует в actual, но не в expected (SQL right outer join)

match - присутствует в expected и actual (SQL inner join)

expected - это то, что я получаю из запроса SQL. У меня много сценариев, когда в СУБД нет столбца actual, поэтому для сравнения пришлось бы использовать Excel. Я могу сравнить его, как правило, используя VLOOKUP, но это отнимает много времени, а также не дает желаемого формата. Я хотел бы получить решение, которое можно сделать , что важно с форматом, как указано выше.

Я открыт для предложений. Я лично делаю это, используя python / pandas, но мои коллеги не привыкли к python, поэтому я бы предпочел решение, которое можно сделать одним нажатием кнопки, или автоматизировать с помощью VBA, или функцию через Excel, в основном все, что Я могу поделиться со своими коллегами по Excel, которые могут ускорить процесс. В настоящее время они повторяют полоскание VLOOKUP->Filter->Copy->Paste to another sheet для всех трех столбцов.

Одно из предложенных решений - https://superuser.com/a/1417235/954024, но оно работает очень медленно и неэффективно, моя система зависла только при использовании этого: (

Мое решение на python:

import pandas as pd
import sys


def find_discrepancies(input_file):
    """
    input: df
    output: formatted df
    """
    df = pd.read_excel(input_file)
    df['match'] = df.loc[df['expected'].isin(df['actual'])].reset_index()[
        'expected']
    df['forward'] = df.loc[df['expected'].isin(
        df['actual']) == False].reset_index()['expected']
    df['backward'] = df.loc[df['actual'].isin(
        df['expected']) == False].reset_index()['actual']
    df = df[['expected', 'match', 'forward', 'backward', 'actual']]
    counts = df.count()
    df.columns = [df.columns[i].capitalize() + ' - ' + str(counts.values[i]) for i in range(5)]
    df.fillna('', inplace=True)

    return df


def main(inputFile, outputFile):
    df = find_discrepancies(inputFile)
    df.to_excel(outputFile, index=False)


if __name__ == '__main__':

    inputFile = sys.argv[1]
    outputFile = sys.argv[2]

    main(inputFile, outputFile)

1 Ответ

1 голос
/ 26 марта 2019

Не самое чистое решение, но этого должно хватить. Мне нужно знать немного больше о ваших настройках данных, чтобы настроить это.

Option Explicit
Sub PopulateColumns()

    Dim i As Long, lastrow As Long
    Dim testitem As String

    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
        testitem = Cells(i, 1).Value

        If Application.CountIf(Range("E:E"), testitem) = 0 Then
            lastrow = Cells(Rows.Count, 3).End(xlUp).Row
            Cells(lastrow + 1, 3).Value = testitem
        ElseIf Application.CountIf(Range("E:E"), testitem) > 0 Then
            lastrow = Cells(Rows.Count, 2).End(xlUp).Row
            Cells(lastrow + 1, 2).Value = testitem
        End If
    Next i

    For i = 2 To Cells(Rows.Count, 5).End(xlUp).Row
        testitem = Cells(i, 5).Value

        If Application.CountIf(Range("A:A"), testitem) = 0 Then
            lastrow = Cells(Rows.Count, 4).End(xlUp).Row
            Cells(lastrow + 1, 4).Value = testitem
        End If
    Next i

Cells(1, 1).Value = "Expected - " & Cells(Rows.Count, 1).End(xlUp).Row - 1
Cells(1, 2).Value = "Match - " & Cells(Rows.Count, 2).End(xlUp).Row - 1
Cells(1, 3).Value = "Forward - " & Cells(Rows.Count, 3).End(xlUp).Row - 1
Cells(1, 4).Value = "Backward - " & Cells(Rows.Count, 4).End(xlUp).Row - 1
Cells(1, 5).Value = "Actual - " & Cells(Rows.Count, 5).End(xlUp).Row - 1

Columns("A:E").AutoFit

For i = 1 To 5
    Cells(1, i).Interior.Color = RGB(168, 207, 141)
    Cells(1, i).Font.Bold = True
    Cells(1, i).HorizontalAlignment = xlCenter
    Cells(1, i).Borders.LineStyle = xlContinuous
Next i


End Sub

img

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...