У меня есть 4 корпуса:
C1 = ['hello','good','good','desk']
C2 = ['nice','good','desk','paper']
C3 = ['red','blue','green']
C4 = ['good']
Я хочу определить список слов, и для каждого - получить вхождение в корпус. так что если
l= ['хорошо','синий']
я получу
res_df = word. C1. C2. C3. C4
good. 2. 1. 0. 1
blue. 0. 0. 1. 0
Мой корпус очень большой, поэтому я ищу эффективный способ. Как лучше всего это сделать?
Спасибо
Я полагаю, вы уже просмотрели docs.python.org/3/library/collections.html#collections.Counter?
Панды могут справиться с этим требованием довольно легко. Вы используете Pandas здесь?
@Sala К моему удивлению, счетчик получает все слова, и мне нужно только подмножество
@TimBiegeleisen Как я могу сделать это с пандами?
@Cranjis Если это о пандах, то почему вы не добавили этот тег к вопросу?
разве C4 не должен иметь 1 в строке res_df с «хорошо»?
@ScottC 10x исправлено






Одна из идей — отфильтровать значения по списку, преобразованному в набор, а затем подсчитать по Counter, последний передать в DataFrame с добавлением 0 и целыми числами:
from collections import Counter
d = {'C1':C1, 'C2':C2, 'C3':C3, 'C4':C4}
s = set(l)
df = (pd.DataFrame({k:Counter([y for y in v if y in s]) for k, v in d.items()})
.fillna(0).astype(int))
print (df)
C1 C2 C3 C4
good 2 1 0 1
blue 0 0 1 0
Если возможно, не существующие значения в списке:
from collections import Counter
l= ['good','blue','non']
d = {'C1':C1, 'C2':C2, 'C3':C3, 'C4':C4}
s = set(l)
df = (pd.DataFrame({k:Counter([y for y in v if y in s]) for k, v in d.items()})
.fillna(0)
.astype(int)
.reindex(l, fill_value=0))
print (df)
C1 C2 C3 C4
good 2 1 0 1
blue 0 0 1 0
non 0 0 0 0
Вы можете использовать счетчик python lib
counts = [[Counter(C)[word] for C in (C1, C2, C3, C4)] for word in l]
res_df = pd.DataFrame(counts, columns=['C1', 'C2', 'C3', 'C4'], index=l)
выход
C1 C2 C3 C4
good 2 1 0 1
blue 0 0 1 0
Другой вариант использования .loc:
df = pd.DataFrame({'C1': Counter(C1), 'C2': Counter(C2), 'C3': Counter(C3), 'C4': Counter(C4)}).loc[l].fillna(0).astype('int')
Пример ниже:
from collections import Counter
import pandas as pd
C1 = ['hello','good','good','desk']
C2 = ['nice','good','desk','paper']
C3 = ['red','blue','green']
C4 = ['good']
l= ['good','blue']
df = pd.DataFrame({'C1': Counter(C1), 'C2': Counter(C2), 'C3': Counter(C3), 'C4': Counter(C4)}).loc[l].fillna(0).astype('int')
print(df)
C1 C2 C3 C4
good 2 1 0 1
blue 0 0 1 0
что вы пробовали, как вы решите это для меньших размеров? .. если вы знаете решение для меньших размеров, почему оно не работает для больших?