Самый быстрый способ проверить, является ли значение или список значений подмножеством списка в Python - PullRequest
2 голосов
/ 08 июля 2019

У меня есть очень большой список списков с именем main_list, содержащий около 13 миллионов списков, каждый из которых содержит 6 номеров.Я ищу способ отфильтровать любой список, который не содержит определенных значений.Например, чтобы создать новый список списков, который включает только списки со значениями 4 и 5, мой код работает следующим образом:

and_include = []
temp_list=[4,5]
for sett in main_list:
    if set(temp_list).issubset(sett):
        and_include.append(sett)

Это занимает около 5 секунд, что может быть довольно раздражающим для частыхиспользовать, поэтому мне было интересно, есть ли более быстрый способ сделать это, используя Numpy или Cython?

Я не очень знаком с Cython, но я пытался реализовать этот способ, скомпилировал его и все, но я получил ошибку.

def andinclude(list main_list,list temp_list):
    and_include=[]
    for sett in main_list:
        if set(temp_list).issubset(sett):
            and_include.append(sett)
    return and_include

Надеюсь, есть более быстрый путь?

Ответы [ 2 ]

2 голосов
/ 08 июля 2019

Вот решение numpy:

import numpy as np

# Randomly generate 2d array of integers
np.random.seed(1)
a = np.random.randint(low=0, high=9, size=(13000000, 6))

# Use numpy indexing to filter rows
results = a[(a == 4).any(axis=1) & (a == 5).any(axis=1)]

Результаты:

In [35]: print(results.shape)
(3053198, 6)

In [36]: print(results[:5])
[[5 5 4 5 5 1]
 [5 5 4 3 8 6]
 [2 5 8 1 1 4]
 [0 5 4 1 1 5]
 [3 2 5 2 4 6]]

Время:

In [37]: %timeit results = a[(a == 4).any(axis=1) & (a == 5).any(axis=1)]
923 ms ± 38.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Если вам нужно преобразовать результаты обратно в список списков, а не в двумерный массив, вы можете использовать:

l = results.tolist()

Это прибавило около 50% времени, необходимого для запуска на моем компьютере., но все равно должно быть быстрее, чем любое решение, включающее циклический просмотр списков Python.

0 голосов
/ 08 июля 2019

Вы можете использовать понимание списка вместо добавления в цикл.Также вы можете захотеть сохранить результат set(temp_list) в локальной переменной, чтобы не вызывать set 13 миллионов раз для того же результата.

...