How to remove several different stems at the end of the word using slicing
Although I understand there are tools such as NLTK to do this for me, however, I would like to understand how I can slice several stems within a list efficiently.
Say my list of words is;
list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
And my common stems I would like to remove may be;
stems = ["s", "es", "ed", "est", "ing", "ly"] etc
With words I do not want stemmed specified as;
noStem = ["walrus", "rest", "wing", "feed"]
I have worked out how to do it for one specific stem like "s". For example, my code would be;
for eachWord in list:
if eachWord not in noStem:
if eachWord[-1] == "s":
eachWord = eachWord[:-1]
stemmedList = stemmedList + [eachWord]
I am not sure how I would apply this to all my stems in a more efficient way.
Thanks for your help and advice!
python
add a comment |
Although I understand there are tools such as NLTK to do this for me, however, I would like to understand how I can slice several stems within a list efficiently.
Say my list of words is;
list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
And my common stems I would like to remove may be;
stems = ["s", "es", "ed", "est", "ing", "ly"] etc
With words I do not want stemmed specified as;
noStem = ["walrus", "rest", "wing", "feed"]
I have worked out how to do it for one specific stem like "s". For example, my code would be;
for eachWord in list:
if eachWord not in noStem:
if eachWord[-1] == "s":
eachWord = eachWord[:-1]
stemmedList = stemmedList + [eachWord]
I am not sure how I would apply this to all my stems in a more efficient way.
Thanks for your help and advice!
python
add a comment |
Although I understand there are tools such as NLTK to do this for me, however, I would like to understand how I can slice several stems within a list efficiently.
Say my list of words is;
list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
And my common stems I would like to remove may be;
stems = ["s", "es", "ed", "est", "ing", "ly"] etc
With words I do not want stemmed specified as;
noStem = ["walrus", "rest", "wing", "feed"]
I have worked out how to do it for one specific stem like "s". For example, my code would be;
for eachWord in list:
if eachWord not in noStem:
if eachWord[-1] == "s":
eachWord = eachWord[:-1]
stemmedList = stemmedList + [eachWord]
I am not sure how I would apply this to all my stems in a more efficient way.
Thanks for your help and advice!
python
Although I understand there are tools such as NLTK to do this for me, however, I would like to understand how I can slice several stems within a list efficiently.
Say my list of words is;
list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
And my common stems I would like to remove may be;
stems = ["s", "es", "ed", "est", "ing", "ly"] etc
With words I do not want stemmed specified as;
noStem = ["walrus", "rest", "wing", "feed"]
I have worked out how to do it for one specific stem like "s". For example, my code would be;
for eachWord in list:
if eachWord not in noStem:
if eachWord[-1] == "s":
eachWord = eachWord[:-1]
stemmedList = stemmedList + [eachWord]
I am not sure how I would apply this to all my stems in a more efficient way.
Thanks for your help and advice!
python
python
asked Nov 21 '18 at 19:32
highfocushighfocus
62
62
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
I would suggest you convert noStem
to a set
so that the check if eachWord not in noStem
is fast. Then you can check if the word endswith
any stem in stems
. If it does, you can use the largest stem that matches and remove it from the word:
lst = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["s", "es", "ed", "est", "ing", "ly"]
noStem = {"walrus", "rest", "wing", "feed"}
stemmedList =
for word in lst:
if word in noStem or not any([word.endswith(stem) for stem in stems]):
stemmedList.append(word)
else:
stem = max([s for s in stems if word.endswith(s)], key=len)
stemmedList.append(word[:len(word) - len(stem)])
print(stemmedList)
# ['another', 'cat', 'walrus', 'relax', 'annoying', 'rest', 'normal', 'hopp', 'class', 'wing', 'feed']
add a comment |
It's much more complicated than this but here goes a starter code using much faster pandas module. Here it goes.
import pandas as pd
import re
word_list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["es", "ed", "est", "ing", "ly", "s"]
# a set for quick lookup
noStem = set(["walrus", "rest", "wing", "feed"])
# build series
words = pd.Series(word_list)
# filter out words in noStem
words = words[words.apply(lambda x: x not in noStem)]
# compile regular explession - performance - join all stems for matching
term_matching = '|'.join(stems)
expr = re.compile(r'(.+?)({})$'.format(term_matching))
df = words.str.extract(expr, expand=True)
df.dropna(how='any', inplace=True)
df.columns = ['words', 'stems']
stemmed_list = df.words.tolist()
I hope it helps ...
add a comment |
I think that isn't a bad start. You just need to add the second loop to be able to work with multiple endings. You can try something like below, (You'll notice I've renamed the variable list
because it's dangerous having variables shadowing built-in names)
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word.endswith(ending):
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Or if as per your comment you don't want to use endswith
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word[-len(ending):] == ending:
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419322%2fhow-to-remove-several-different-stems-at-the-end-of-the-word-using-slicing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would suggest you convert noStem
to a set
so that the check if eachWord not in noStem
is fast. Then you can check if the word endswith
any stem in stems
. If it does, you can use the largest stem that matches and remove it from the word:
lst = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["s", "es", "ed", "est", "ing", "ly"]
noStem = {"walrus", "rest", "wing", "feed"}
stemmedList =
for word in lst:
if word in noStem or not any([word.endswith(stem) for stem in stems]):
stemmedList.append(word)
else:
stem = max([s for s in stems if word.endswith(s)], key=len)
stemmedList.append(word[:len(word) - len(stem)])
print(stemmedList)
# ['another', 'cat', 'walrus', 'relax', 'annoying', 'rest', 'normal', 'hopp', 'class', 'wing', 'feed']
add a comment |
I would suggest you convert noStem
to a set
so that the check if eachWord not in noStem
is fast. Then you can check if the word endswith
any stem in stems
. If it does, you can use the largest stem that matches and remove it from the word:
lst = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["s", "es", "ed", "est", "ing", "ly"]
noStem = {"walrus", "rest", "wing", "feed"}
stemmedList =
for word in lst:
if word in noStem or not any([word.endswith(stem) for stem in stems]):
stemmedList.append(word)
else:
stem = max([s for s in stems if word.endswith(s)], key=len)
stemmedList.append(word[:len(word) - len(stem)])
print(stemmedList)
# ['another', 'cat', 'walrus', 'relax', 'annoying', 'rest', 'normal', 'hopp', 'class', 'wing', 'feed']
add a comment |
I would suggest you convert noStem
to a set
so that the check if eachWord not in noStem
is fast. Then you can check if the word endswith
any stem in stems
. If it does, you can use the largest stem that matches and remove it from the word:
lst = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["s", "es", "ed", "est", "ing", "ly"]
noStem = {"walrus", "rest", "wing", "feed"}
stemmedList =
for word in lst:
if word in noStem or not any([word.endswith(stem) for stem in stems]):
stemmedList.append(word)
else:
stem = max([s for s in stems if word.endswith(s)], key=len)
stemmedList.append(word[:len(word) - len(stem)])
print(stemmedList)
# ['another', 'cat', 'walrus', 'relax', 'annoying', 'rest', 'normal', 'hopp', 'class', 'wing', 'feed']
I would suggest you convert noStem
to a set
so that the check if eachWord not in noStem
is fast. Then you can check if the word endswith
any stem in stems
. If it does, you can use the largest stem that matches and remove it from the word:
lst = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["s", "es", "ed", "est", "ing", "ly"]
noStem = {"walrus", "rest", "wing", "feed"}
stemmedList =
for word in lst:
if word in noStem or not any([word.endswith(stem) for stem in stems]):
stemmedList.append(word)
else:
stem = max([s for s in stems if word.endswith(s)], key=len)
stemmedList.append(word[:len(word) - len(stem)])
print(stemmedList)
# ['another', 'cat', 'walrus', 'relax', 'annoying', 'rest', 'normal', 'hopp', 'class', 'wing', 'feed']
edited Nov 21 '18 at 19:54
answered Nov 21 '18 at 19:41
sliderslider
8,55811331
8,55811331
add a comment |
add a comment |
It's much more complicated than this but here goes a starter code using much faster pandas module. Here it goes.
import pandas as pd
import re
word_list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["es", "ed", "est", "ing", "ly", "s"]
# a set for quick lookup
noStem = set(["walrus", "rest", "wing", "feed"])
# build series
words = pd.Series(word_list)
# filter out words in noStem
words = words[words.apply(lambda x: x not in noStem)]
# compile regular explession - performance - join all stems for matching
term_matching = '|'.join(stems)
expr = re.compile(r'(.+?)({})$'.format(term_matching))
df = words.str.extract(expr, expand=True)
df.dropna(how='any', inplace=True)
df.columns = ['words', 'stems']
stemmed_list = df.words.tolist()
I hope it helps ...
add a comment |
It's much more complicated than this but here goes a starter code using much faster pandas module. Here it goes.
import pandas as pd
import re
word_list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["es", "ed", "est", "ing", "ly", "s"]
# a set for quick lookup
noStem = set(["walrus", "rest", "wing", "feed"])
# build series
words = pd.Series(word_list)
# filter out words in noStem
words = words[words.apply(lambda x: x not in noStem)]
# compile regular explession - performance - join all stems for matching
term_matching = '|'.join(stems)
expr = re.compile(r'(.+?)({})$'.format(term_matching))
df = words.str.extract(expr, expand=True)
df.dropna(how='any', inplace=True)
df.columns = ['words', 'stems']
stemmed_list = df.words.tolist()
I hope it helps ...
add a comment |
It's much more complicated than this but here goes a starter code using much faster pandas module. Here it goes.
import pandas as pd
import re
word_list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["es", "ed", "est", "ing", "ly", "s"]
# a set for quick lookup
noStem = set(["walrus", "rest", "wing", "feed"])
# build series
words = pd.Series(word_list)
# filter out words in noStem
words = words[words.apply(lambda x: x not in noStem)]
# compile regular explession - performance - join all stems for matching
term_matching = '|'.join(stems)
expr = re.compile(r'(.+?)({})$'.format(term_matching))
df = words.str.extract(expr, expand=True)
df.dropna(how='any', inplace=True)
df.columns = ['words', 'stems']
stemmed_list = df.words.tolist()
I hope it helps ...
It's much more complicated than this but here goes a starter code using much faster pandas module. Here it goes.
import pandas as pd
import re
word_list = ["another", "cats", "walrus", "relaxed", "annoyingly", "rest", "normal", "hopping", "classes", "wing", "feed"]
stems = ["es", "ed", "est", "ing", "ly", "s"]
# a set for quick lookup
noStem = set(["walrus", "rest", "wing", "feed"])
# build series
words = pd.Series(word_list)
# filter out words in noStem
words = words[words.apply(lambda x: x not in noStem)]
# compile regular explession - performance - join all stems for matching
term_matching = '|'.join(stems)
expr = re.compile(r'(.+?)({})$'.format(term_matching))
df = words.str.extract(expr, expand=True)
df.dropna(how='any', inplace=True)
df.columns = ['words', 'stems']
stemmed_list = df.words.tolist()
I hope it helps ...
answered Nov 21 '18 at 21:50
AResemAResem
1114
1114
add a comment |
add a comment |
I think that isn't a bad start. You just need to add the second loop to be able to work with multiple endings. You can try something like below, (You'll notice I've renamed the variable list
because it's dangerous having variables shadowing built-in names)
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word.endswith(ending):
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Or if as per your comment you don't want to use endswith
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word[-len(ending):] == ending:
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
add a comment |
I think that isn't a bad start. You just need to add the second loop to be able to work with multiple endings. You can try something like below, (You'll notice I've renamed the variable list
because it's dangerous having variables shadowing built-in names)
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word.endswith(ending):
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Or if as per your comment you don't want to use endswith
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word[-len(ending):] == ending:
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
add a comment |
I think that isn't a bad start. You just need to add the second loop to be able to work with multiple endings. You can try something like below, (You'll notice I've renamed the variable list
because it's dangerous having variables shadowing built-in names)
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word.endswith(ending):
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Or if as per your comment you don't want to use endswith
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word[-len(ending):] == ending:
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
I think that isn't a bad start. You just need to add the second loop to be able to work with multiple endings. You can try something like below, (You'll notice I've renamed the variable list
because it's dangerous having variables shadowing built-in names)
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word.endswith(ending):
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
Or if as per your comment you don't want to use endswith
stemmed_list =
for word in word_list:
if word not in noStem:
for ending in stems:
if word[-len(ending):] == ending:
word = word[:-len(ending)]
break # This will prevent iterating over all endings once match is found
stemmed_list.append(word)
edited Nov 22 '18 at 9:47
answered Nov 21 '18 at 19:53
Sven HarrisSven Harris
2,1861516
2,1861516
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
add a comment |
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
Thank you for this comment, this is the idea I was aiming for. If I may ask a second question, is it possible to do this without the endswith() method? I'd like to use a slice constructor to make this work.
– highfocus
Nov 22 '18 at 9:14
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
@highfocus that is possible (see my edit) although I don't necessarily know why you would want to as endswith is a nice built-in convenience method
– Sven Harris
Nov 22 '18 at 9:49
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419322%2fhow-to-remove-several-different-stems-at-the-end-of-the-word-using-slicing%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown