Lookup multiple words in a sentence in a Dataframe and convert to a sum of scores

Viewed 77

I have the following dataframe:

    Sentence
0   Cat is a big lion
1   Dogs are descendants of wolf
2   Elephants are pachyderm
3   Pachyderm animals include rhino, Elephants and hippopotamus

I need to create a python code which looks at the words in sentence above and calculates the sum of scores for each based on following distinct data frame.

Name          Score
cat             1
dog             2
wolf            2
lion            3
elephants       5
rhino           4
hippopotamus    5

For example, for row 0, the score will be 1 (cat) + 3 (lion) = 4

I am looking to create an output that looks like following.

    Sentence                                                      Value
0   Cat is a big lion                                                4
1   Dogs are descendants of wolf                                     4
2   Elephants are pachyderm                                          5
3   Pachyderm animals include rhino, Elephants and hippopotamus      14
3 Answers

As a first effort, you can try a split and map-based approach, and then compute the score using groupby.

v = df1['Sentence'].str.split(r'[\s.!?,]+', expand=True).stack().str.lower()
df1['Value'] = (
    v.map(df2.set_index('Name')['Score'])
     .sum(level=0)
     .fillna(0, downcast='infer'))

df1
                                            Sentence  Value
0                                  Cat is a big lion      4
1                       Dogs are descendants of wolf      4  # s/dog/dogs in df2  
2                            Elephants are pachyderm      5
3  Pachyderm animals include rhino, Elephants and...     14

nltk

You may need to download stuff

import nltk

nltk.download('punkt')

Then set up stemming and tokenizing

from nltk.stem import PorterStemmer
from nltk.tokenize import word_tokenize

ps = PorterStemmer()

Create a handy dictionary

m = dict(zip(map(ps.stem, scores.Name), scores.Score))

And generate scores

def f(s):
  return sum(filter(None, map(m.get, map(ps.stem, word_tokenize(s)))))

df.assign(Score=[*map(f, df.Sentence)])

                                            Sentence  Score
0                                  Cat is a big lion      4
1                       Dogs are descendants of wolf      4
2                            Elephants are pachyderm      5
3  Pachyderm animals include rhino, Elephants and...     14

Trying to using findall with re re.I

df.Sentence.str.findall(df1.Name.str.cat(sep='|'),flags=re.I).\
   map(lambda x : sum([df1.loc[df1.Name==str.lower(y),'Score' ].values for y in x])[0])
Out[49]: 
0     4
1     4
2     5
3    14
Name: Sentence, dtype: int64
Related