Вернуть список каждого слова в ячейке панды и общее количество этого слова во всем столбце

У меня есть фрейм данных панд, df, который выглядит так:

             column1
0   apple is a fruit
1        fruit sucks
2  apple tasty fruit
3   fruits what else
4      yup apple map
5   fire in the hole
6       that is true

Я хочу создать column2, который является списком каждого слова в строке и общим количеством каждого слова во всем столбце. Таким образом, на выходе будет что-то вроде этого....

    column1            column2
0   apple is a fruit   [('apple', 3),('is', 2),('a', 1),('fruit', 3)]
1        fruit sucks   [('fruit', 3),('sucks', 1)]

Я пытался использовать sklearn, но не смог достичь вышеуказанного. Нужна помощь.

from sklearn.feature_extraction.text import CountVectorizer
v = CountVectorizer()
x = v.fit_transform(df['text'])

2 ответа

Решение

Вот один способ, который дает желаемый результат, хотя избегает sklearn полностью:

def counts(data, column):
    full_list = []
    datr = data[column].tolist()
    total_words = " ".join(datr).split(' ')
    # per rows
    for i in range(len(datr)):
        #first per row get the words
        word_list = re.sub("[^\w]", " ",  datr[i]).split()
        #cycle per word
        total_row = []
        for word in word_list:
            count = []
            count = total_words.count(word)
            val = (word, count)
            total_row.append(val)
        full_list.append(total_row)
    return full_list

df['column2'] = counts(df,'column1')
df
         column1                                    column2
0   apple is a fruit  [(apple, 3), (is, 2), (a, 1), (fruit, 3)]
1        fruit sucks                   [(fruit, 3), (sucks, 1)]
2  apple tasty fruit       [(apple, 3), (tasty, 1), (fruit, 3)]
3   fruits what else        [(fruits, 1), (what, 1), (else, 1)]
4      yup apple map           [(yup, 1), (apple, 3), (map, 1)]
5   fire in the hole  [(fire, 1), (in, 1), (the, 1), (hole, 1)]
6       that is true            [(that, 1), (is, 2), (true, 1)]

Я не знаю, можете ли вы сделать это, используя scikit-learn, но вы можете написать функцию, а затем использовать apply() применить его на вашем DataFrame или же Series,

Вот как вы могли бы сделать это для вашего примера:

test = pd.DataFrame(['apple is a fruit', 'fruit sucks', 'apple tasty fruit'], columns = ['A'])

def a_function(row):
    splitted_row = str(row.values[0]).split()
    word_occurences = []
    for word in splitted_row:
        column_occurences = test.A.str.count(word).sum()
        word_occurences.append((word, column_occurences))
    return word_occurences

test.apply(a_function, axis = 1)

# Output
0    [(apple, 2), (is, 1), (a, 4), (fruit, 3)]
1                     [(fruit, 3), (sucks, 1)]
2         [(apple, 2), (tasty, 1), (fruit, 3)]
dtype: object

Как видите, главная проблема в том, что test.A.str.count(word) будет считать все случаи wordгде шаблон назначен word находится внутри строки. Вот почему "a" отображается как происходящее 4 раза. Это, вероятно, должно быть легко исправлено с помощью некоторых регулярных выражений (что я не очень хорошо умею).

Или вы можете использовать этот обходной путь внутри функции выше, если вы хотите потерять несколько слов:

if word not in ['a', 'is']:  # you can add here more useless words
    word_occurences.append((word, column_occurences))
Другие вопросы по тегам