Найти совпадения в двух очень больших списках в Excel - PullRequest
0 голосов
/ 15 января 2019

У меня есть два очень больших списка. Один содержит около 130 000 элементов (список А), другой - около 600 000 столбцов (список Б). Мне нужно знать, какие элементы в списке A появляются в списке B, но я сталкиваюсь с ограничением по времени обработки.

Мой обычный подход был бы примерно таким:

Поместите Список A в столбец A и Список B в столбец B. В C1 укажите следующее:

=Not(IsError(Match(A1,B$1:B$600000,0)))

Тогда я бы заполнил это до C130000.

Очевидно, это будет работать с двумя списками длиной 100 пунктов. Однако списки настолько велики, что моему компьютеру это займет слишком много времени.

Есть ли метод, который я могу использовать в Excel, который бы работал для списков такого размера, не занимая месяц для обработки? Или мне нужно начать искать другие варианты?

Использование Office 365

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Сортировка списка 600000 в столбце B. Затем в столбце C используйте

=IF(VLOOKUP(A1,$B$1:$B$600000,1,True)=A1,"Match","")

И скопируйте формулу вниз для 130000 элементов в столбце А.

Расчет занимает на моей машине 0,04 секунды для чуть более 100000 элементов в столбце A (скорость двоичного поиска поразительна)

0 голосов
/ 15 января 2019

Код ниже проверил 100 пунктов в течение 6,2 секунды. При этом он должен закончить работу на 130 000 в течение 15 минут. Вы можете использовать тот же тест, чтобы увидеть, сколько времени потребуется для обработки более длинных строк.

Private Sub SearchForDuplicates()

    Dim Rng As Range
    Dim Arr As Variant, Arr2 As Variant
    Dim R As Long, i As Long
    Dim Tstart As Single

    Tstart = Timer
    Set Rng = Range(Cells(1, 1), Cells(600000, 1))
    Arr = Rng.Value
    ReDim Arr2(1 To 130000)
    Randomize
    For R = 1 To UBound(Arr2)
        Arr2(R) = Int((1200000 - 1 + 1) * Rnd + 1)
'        If R Mod 10000 = 0 Then Debug.Print R, Timer - Tstart
    Next R
    For R = 1 To UBound(Arr2)
        For i = 1 To UBound(Arr)
            If Arr2(R) = Arr(i, 1) Then
                Debug.Print "Found"
                Exit For
            End If
        Next i
        If R Mod 100 = 0 Then Exit For
'        If R Mod 1000 = 0 Then Debug.Print R, Timer - Tstart
    Next R
'    Rng.Value = Arr
    Debug.Print Timer - Tstart
End Sub

Обратите внимание, что время, которое я измерил, включает время на настройку 730 000 строк для тестирования

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