Я пытаюсь сравнить два вложенных списка строк друг с другом и искать самый быстрый способ. Для этого я в настоящее время вычисляю Jaccard-index (пересечение/объединение) между каждым из элементов вложенных списков. Пример:
list1=[["abc","def","ghi"],["jkl","mno"]]
list2=[["pqr","def","stu"],["jkl","mno","vwx"]]
В этом примере первый "кластер" первого списка сравнивается с каждым из кластера второго списка, что приводит к 4 (2 * 2) разным идентификаторам jaccard.
Однако моя проблема заключается в том, что каждый мой список содержит около 500 000 кластеров/элементов (подписок). С моим текущим кодом мне потребуется около 2 недель для вычисления. В этот момент я не могу уменьшить время вычислений и обратиться за помощью.
Текущий код:
for i1 in list1:
for i2 in list2:
intersection = set(i1) & set(i2)
union = set(i1) | set(i2)
jaccard = (len(intersection) / len(union)) * 100
if jaccard > 1:
#write to file....
это не даст вам большого повышения производительности, но если ваши внутренние списки коротки (2 или 3 элемента, как в вашем примере), одна вещь, которую вы могли бы сделать, - это пересечь \union списки сами, обычно быстрее сделать это следующим образом: [val for val in i1 if val in i2]
вместо такого set(i1) & set(i2)
для пересечения, и для объединения используйте это: [val for val in i1 if val not in i2] + i2
.
Я попытался сравнить оба метода, в которых оба списка содержат около 500 тыс. подсписей, и каждый подсписщик содержит 3 случайные строки и сокращает время, затрачиваемое на одну итерацию (внешнего цикла), примерно в среднем от 0,6 секунды до примерно 0,45 секунды (усреднение первые 100 циклов), по крайней мере, на моей машине.
причина такого рода может повлиять на производительность на 25%, потому что у python много накладных расходов при манипулировании данными, которые, к счастью, иногда можно минимизировать, но я думаю, что урок из этого (к сожалению) состоит в том, чтобы не использовать python для больших наборов данных, потому что это очень неэффективен, когда дело касается таких вещей