Группировать похожие слова/предложения в столбце pandas

avatar
jason
8 апреля 2018 в 09:51
1622
2
0

Я пытался использовать код:

Counter(" ".join(df["text"]).split()).most_common(100)

Чтобы получить наиболее распространенные слова, но я хотел подсчитать общие слова в предложениях. Например:

1. A123 B234 C345 test data.
2. A123 B234 C345 D555 test data.
3. A123 B234 test data.
4. A123 B234 C345 more data.

Я хотел подсчитать:

 A123 B234 data- 4
 A123 B234 test data - 3
 A123 B234 C345 test data- 3

Я ищу группу слов, которые являются общими и имеют большое количество. Как я могу получить это в pandas/python

Примеры предложений:

Money transferred from xyz@abc.com to account no.123
Money transferred from xyz@abc.net to account no.abc
Money failed transferring from xyz@abc. to account no.cde
Money transferred from example@yyy.com to account no.www
Money failed transferring from xyz@abc.com to account no.ttt
Источник
MaxU
8 апреля 2018 в 10:38
0

Я не понимаю ваш желаемый набор данных - можете ли вы уточнить?

jason
8 апреля 2018 в 12:04
0

@MaxU Искомый набор данных представляет собой группу слов, которые совпадают в каждом предложении вместе с количеством.

jezrael
8 апреля 2018 в 12:10
0

@jason - сколько строк в кадре данных? Сколько уникальных слов?

jason
8 апреля 2018 в 12:20
0

@jezrael Я смотрю на сортировку значений в порядке убывания разбиваемых слов в предложении и группировку их вместе с подсчетом. Что-то в этом ряду. Как в моем примере.

jezrael
8 апреля 2018 в 12:24
0

@jason - я спрашиваю, потому что, если много строк или много уникальных слов, я не уверен, должно ли мое решение быть быстрым ... Пожалуйста, проверьте это.

jason
8 апреля 2018 в 12:28
0

@jezrael Ничего страшного, если на это потребуется время. Я проверю это! Спасибо, что поделились ответом :)

Ответы (2)

avatar
jezrael
8 апреля 2018 в 12:23
0

Одно возможное решение:

df = df['col'].str.get_dummies(' ')
print (df)
   A123  B234  C345  D555  data  more  test
0     1     1     1     0     1     0     1
1     1     1     1     1     1     0     1
2     1     1     0     0     1     0     1
3     1     1     1     0     1     1     0

Альтернатива:

from sklearn.preprocessing import MultiLabelBinarizer

mlb = MultiLabelBinarizer()
df = pd.DataFrame(mlb.fit_transform(df['col'].str.split()),
                  columns=mlb.classes_, 
                  index=df.index)
print (df)
   A123  B234  C345  D555  data  more  test
0     1     1     1     0     1     0     1
1     1     1     1     1     1     0     1
2     1     1     0     0     1     0     1
3     1     1     1     0     1     1     0

Получить все комбинации от min_length до max всех комбинаций столбцов (words):

from  itertools import combinations
a = df.columns
min_length = 3
comb = [j for i in range(len(a), min_length -1, -1) for j in combinations(a,i)]

В значениях счетчика понимания списка:

df1 = pd.DataFrame([(', '.join(x), df.loc[:, x].all(axis=1).sum(), len(x)) for x in comb], 
                    columns=['words','count','len'])

TOP = 2
TOP_count = sorted(df1['count'].unique())[-TOP:]
df1 = df1[df1['count'].isin(TOP_count)].sort_values(['count', 'len'], ascending=False)
print (df1)
                     words  count  len
66        A123, B234, data      4    3
30  A123, B234, C345, data      3    4
37  A123, B234, data, test      3    4
64        A123, B234, C345      3    3
68        A123, B234, test      3    3
70        A123, C345, data      3    3
77        A123, data, test      3    3
80        B234, C345, data      3    3
87        B234, data, test      3    3

РЕДАКТИРОВАТЬ:

Чистое решение Python:

from  itertools import combinations, takewhile
from collections import Counter

min_length = 3
d = Counter()
for a in df['col'].str.split():
    for i in range(len(a), min_length -1, -1):
        for j in combinations(a,i):
            d[j] +=1
#print (d)

#https://coderhelper.com/a/26831143
def get_items_upto_count(dct, n):
  data = dct.most_common()
  val = data[n-1][1] #get the value of n-1th item
  #Now collect all items whose value is greater than or equal to `val`.
  return list(takewhile(lambda x: x[1] >= val, data))

L = get_items_upto_count(d, 2)

s = pd.DataFrame(L, columns=['val','count'])
print (s)
                        val  count
0        (A123, B234, data)      4
1  (A123, B234, C345, data)      3
2  (A123, B234, test, data)      3
3        (A123, B234, C345)      3
4        (A123, B234, test)      3
5        (A123, C345, data)      3
6        (A123, test, data)      3
7        (B234, C345, data)      3
8        (B234, test, data)      3
jason
10 апреля 2018 в 09:05
0

Привет Изреаль! Я добавил примеры предложений сверху. Пожалуйста, взгляните :)

jezrael
10 апреля 2018 в 09:20
0

@jason - пожалуйста, проверьте чат.

avatar
vumaasha
8 апреля 2018 в 09:54
0

Используйте groupby с несколькими столбцами в качестве входных данных, за которыми следует метод размера

df.groupby(['col1','col2','col3']).size().sort_values()
jason
8 апреля 2018 в 09:56
0

Привет Вумааша. Пожалуйста, объясни