Как мне найти самые часто используемые слова по какой-то формуле с другим столбцом

#pandas #dataframe

#pandas #фрейм данных

Вопрос:

Мой фрейм данных выглядит следующим образом:

 id `  text                             c1
1     Hello world how are you people    1 
2     Hello people I am fine  people    1
3     Good Morning people               0
4     Good Evening                      0
  

Теперь я хочу найти наиболее часто используемое слово другим способом, позвольте мне объяснить.

Позвольте мне сначала показать вам ожидаемый результат, а затем я объясню:

 Hello - 2
People - 1
world - 1
how - 1
are - 1
you - 1
I - 1
am - 1
fine - 1
  

Что я пытаюсь сказать: здесь people в 3 строках 3 раза. Но количество отображается только 1 в выходных данных. Потому что:

строка 1 содержит people и c1 = 1 строка 2 содержит people и c1 = 1 строка 3 содержит people и c1 = 0

Итак, row1 row2 — row3 = 1 (поскольку значения row1 и row2 равны 1, а row3 равно 0)

Таким же образом, Hello значение s равно 2 на выходе, потому что

строка 1 содержит hello и c1 = 1 строка 2 содержит hello и c1 = 1

Итак, row1 row2 = 2

Я не хочу создавать новый столбец выходных данных, просто хочу его распечатать.

Я использую это для подсчета наиболее часто используемых слов

print(pd.Series(' '.join(df['text']).lower().split()).value_counts()[:10])

Но я знаю, как вычислять вещи по-моему

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

1. Для people 1 1-0 = 1. Как? Это должно быть 2

2. Я не хочу добавлять c1 , потому что c1 равно 0, люди получают один отрицательный балл.

3. Итак, вы хотите проверить, появилось ли слово в строке, затем вы добавляете точку, если c1 равно 1, остальное вы вычитаете. Верно?

4. Да. Люди появляются 2 раза, когда c1 равно 1, так что это дает 2 балла. Но тогда 1 балл вычитается, потому что c1 равно 0.

5. Ты знаешь ответ, братан?

Ответ №1:

Вы можете использовать defaultdict для значений хранилища — первый столбец zip с ci , зациклить их с Counter и добавить, если c1 == 0 добавить отрицательные значения.

Последний фильтр учитывает только положительное значение или 0 при понимании словаря:

 from collections import Counter, defaultdict

zipped = zip(df['text'], df['c1'])
d = defaultdict(int)

for a, b in zipped:
    c = Counter(set(a.lower().split()))
    for k, v in c.items():
        if b == 0:
            v = -v
        d[k]  = v

d = {k: v for k, v in d.items() if v > 0}  
print (d)
{'are': 1, 'hello': 2, 'how': 1,'people': 1, 'world': 1, 'you': 1, 'i': 1, 'am': 1, 'fine': 1}
  

Аналогичное решение, если значения в c1 отсортированы — сначала все 1 , а затем все 0 :

 from collections import Counter, defaultdict

df = df.sort_values('c1', ascending=False)

zipped = zip(df['text'], df['c1'])
d = defaultdict(int)

for a, b in zipped:
    c = Counter(set(a.lower().split()))
    for k, v in c.items():
        if (b == 0) and (k in d):
            d[k] -= v
        elif (b == 1):
            d[k]  = v

print (d)

defaultdict(<class 'int'>, {'are': 1, 'hello': 2, 'how': 1, 'people': 1, 
                            'world': 1, 'you': 1, 'i': 1, 'am': 1, 'fine': 1})
  

 df = pd.DataFrame({'val': list(d.keys()), 
                   'No': list(d.values())}).sort_values('No', ascending=False)
print (df)
      val  No
1   hello   2
0     are   1
2     how   1
3  people   1
4   world   1
5     you   1
6       i   1
7      am   1
8    fine   1
  

 s = pd.Series(d).sort_values(ascending=False)
print (s)
hello     2
fine      1
am        1
i         1
you       1
world     1
people    1
how       1
are       1
dtype: int64
  

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

1. Большое спасибо, не могли бы вы также рассказать мне, как сортировать d по value и печатать?

2. @johndoe — Конечно, вам нужен вывод последовательно?

3. Серия была бы лучше, но это тоже хорошо. Я просто хочу их увидеть и проанализировать

4. @johndoe — Или фрейм данных с 2 столбцами?