#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 столбцами?