Подсчет общих значений из нескольких списков в python

#python #python-3.x #list #dataframe

Вопрос:

У меня есть несколько списков, и я хочу найти общие ценности и посчитать их. например, предположим, что у меня есть следующие списки.

 l1=[1,22,63,4,5,66,7]
l2=[1,22,3,5,6,4]
l3=[1,2,3,5,66,4,70]
 

ожидаемый результат:

введите описание изображения здесь

1 является общим во всех списках, поэтому он занимает 3. аналогично, 6 только в одном списке он занимает 1.

Я попробовал метод пересечения, но он просто находит общие значения.

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

1. Вы хотите, чтобы результат был a pandas.DataFrame ?

2. Фрейм данных или словарь-и то, и другое прекрасно.

3. являются ли номера в каждом списке уникальными или есть дубликаты?

4. списки будут уникальными.

Ответ №1:

Первое и краткое решение благодаря благодарности от @HenryEcker:

 l1=[1,22,63,4,5,66,7]
l2=[1,22,3,5,6,4]
l3=[1,2,3,5,66,4,70]
lst = l1 l2 l3
df = pd.DataFrame(lst, columns=['ID']).value_counts().reset_index(name='rank')
 

Второе решение: (Вы можете сначала объединить три списка с l1 l2 l3 помощью then с Counter помощью count, а затем создать dict , а затем преобразовать dict в pandas .)

 from collections import Counter

l1=[1,22,63,4,5,66,7]
l2=[1,22,3,5,6,4]
l3=[1,2,3,5,66,4,70]
lst = l1 l2 l3

df = pd.DataFrame(Counter(lst).items(), columns=['ID', 'rank'])
df = df.sort_values('rank',ascending=False)

print(df)
 

Выход:

введите описание изображения здесь

Время выполнения двух решений: ( %timeit известно как линейная магия в IPython.(Дополнительная магическая информация из документации здесь))

 %timeit pd.DataFrame(Counter(lst).items(), columns=['ID', 'rank']).sort_values('rank',ascending=False)
# 952 µs ± 222 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit pd.DataFrame(lst, columns=['ID']).value_counts().reset_index(name='rank')
# 2.75 ms ± 701 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
 

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

1. В этом нет необходимости Counter или sort_values вообще нет. Просто используйте value_counts : df = pd.DataFrame(lst, columns=['ID']).value_counts().reset_index(name='rank')

2. @MahipalSingh добро пожаловать, чувак, хорошо проведи время :)))

3. @HenryEcker большое спасибо, я редактирую ответ сейчас. большое спасибо, я здесь для того, чтобы учиться у вас, я рад вашим советам

Ответ №2:

Создать словарь рангов довольно просто:

 common = {}
for val in set(l1 l2 l3):
    common[val] = l1.count(val)   l2.count(val)   l3.count(val)
 

где общее, наконец, равно:

 {1: 3, 66: 2, 3: 2, 4: 3, 5: 3, 6: 1, 7: 1, 2: 1, 70: 1, 22: 2, 63: 1}
 

Ответ №3:

ниже приведен диктант с рангами (внешняя библиотека не требуется)

 from collections import defaultdict

l1 = [1, 22, 63, 4, 5, 66, 7]
l2 = [1, 22, 3, 5, 6, 4]
l3 = [1, 2, 3, 5, 66, 4, 70]

data = defaultdict(int)

distinct = set()
distinct.update(l1)
distinct.update(l2)
distinct.update(l3)
print(distinct)
for v in distinct:
    for l in [l1, l2, l3]:
        if v in l:
            data[v]  = 1
print(data)
 

выход

 defaultdict(<class 'int'>, {1: 3, 66: 2, 3: 2, 4: 3, 5: 3, 6: 1, 7: 1, 2: 1, 70: 1, 22: 2, 63: 1})
 

Ответ №4:

просто стандартная библиотека, никаких панд, использование collections.Counter и itertools.chain

 from collections import Counter
from itertools import chain

l1=[1,22,63,4,5,66,7]
l2=[1,22,3,5,6,4]
l3=[1,2,3,5,66,4,70]

print(Counter(chain(l1, l2, l3)))
 

выход

 Counter({1: 3, 4: 3, 5: 3, 22: 2, 66: 2, 3: 2, 63: 1, 7: 1, 6: 1, 2: 1, 70: 1})