问题
I have a shortcode as following. try to use .apply
to call a function. but it always gives me the error saying the function is not callable.
def awesome_count():
return 10
products['awesome'] = products['word_count'].apply(awesome_count())
AssertionError Traceback (most recent call last)
<ipython-input-45-493b4bfe94cc> in <module>()
----> 1 products['awesome'] = products['word_count'].apply(awesome_count())
C:\Users\twu\AppData\Local\Dato\Dato Launcher\lib\site-packages\graphlab\data_structures\sarray.pyc in apply(self, fn, dtype, skip_undefined, seed)
1598 [0.0, 1.0, 2.0]
1599 """
-> 1600 assert callable(fn), "Input function must be callable."
1601
1602 dryrun = [fn(i) for i in self.head(100) if i is not None]
AssertionError: Input function must be callable.
Can somebody help me out?
回答1:
There are a couple of things that I think will help you with this problem. The first one is converting your "awesome_count" function to a lambda function. Assuming here that the goal of awesome_count is to return the number of times the word "awesome" appears, I know that products['word_count'] contains a dictionary of words and counts (i.e. "and" => 5, "awesome" => 2, "awful = "1"). The hard work here is already done for you since you have all of the counts in products['word_count']. The only thing to be careful of is that the word you're looking for might not exist in the list.
def awesome_count():
if 'awesome' in products['word_count']:
return products['word_count']['awesome']
else
return 0L
The function here checks to see if "awesome" is in the word list. If it is, then we just return products['word_count']['awesome'] (i.e. the number of times awesome occurs). If 'awesome' does not exist, then we default to 0.
So let's turn this into a lambda. Based on his line:
products['awesome'] = products['word_count'].apply(awesome_count())
Each call to the lambda function is passing in products['word_count']. In our lambda function, this will be x.
lambda x: x['awesome'] if 'awesome' in x else 0L
This is the same as above, but in the lambda format. So combine that for:
products['awesome'] = products['word_count'].apply(lambda x: x['awesome'] if 'awesome' in x else 0L)
This will work, but we can do better. Instead of hard coding the word 'awesome', let's use something more generic:
word='awesome'
products[word] = products['word_count'].apply(lambda x: x[word] if word in x else 0L)
Now we have something significantly more generic that we can plug any word into. So let's say we have a list of words we need counts for. We can do this for everything in the list.
word_list = ['awesome','and','some','other','words']
for word in word_list:
products[word] = products['word_count'].apply(lambda x: x[word] if word in x else 0L)
This is a nice and generic solution that can be used to on any number of words. Happy coding.
回答2:
You have to send each row to the function for processing. So the function needs to receive an argument and then do the processing. That is why you are receiving such an error. Notice that you do not need the prentices for the function as it parses the whole SFrame in this case The solution goes like this:
def awesome_count(x):
if 'awesome' in x:
return x['awesome']
else
return 0
products['awesome'] = products['word_count'].apply(awesome_count)
回答3:
You have to pass a user-defined or built-in function or method, or a class object to the apply
method, if you pass awesome_count()
you will be passing the return value (10
) to the apply
method, you have to remove the parenthesis:
def awesome_count():
return 10
products['awesome'] = products['word_count'].apply(awesome_count)
回答4:
I think the function has be called within a lambda function. This code works for me:
import graphlab
sf = graphlab.SFrame({'a': [1, 2, 3]})
def awesome_count():
return 10
sf['a2'] = sf['a'].apply(lambda x: awesome_count())
回答5:
Your words dictonary is something like this:
wordsdict = {"this":5, "is":2, "a":1, "really":4, "awesome":10, "string":12, "Awesome":20, "AWESOME":30, "yeah":1}
This is what you are asking: returns the count associated.
def awesome_count(wordsdict):
if 'awesome' in wordsdict:
return wordsdict['awesome']
Now you want to generalise this with a list of words which could be potential column names:
products = graphlab.SFrame(...)
words = ["awesome", "great", "good", "fantastic"]
for word in words:
products[word] = products['word_count'].apply(lambda x: x[word] if word in x)
回答6:
You can create a simple function that accepts the search text and the key word to search:
def word_count(search_text, search_word):
word_count=search_text.split(" ").count(search_word)
return word_count
Then specify the word to search using a lambda:
products['ColumnWithTextToSearch'].apply(lambda x: word_count(x, 'awesome'))
回答7:
I'm in the same Coursera class.
goal/intention:
goal is to create a column products[‘awesome’] where each row contains the number of times the word ‘awesome’ showed up in the review for the corresponding product, and 0 if the review didn’t show up. One way to do this is to look at the each row ‘word_count’ column and follow this logic:
If ‘awesome’ shows up in the word counts for a particular product (row of the products SFrame), then we know how often ‘awesome’ appeared in the review, if ‘awesome’ doesn’t appear in the word counts, then it didn’t appear in the review, and we should set the count for ‘awesome’ to 0 in this review.
Desired approach:
products['awesome'] = products['word_count'].apply(awesome_count)
Finally, I need to do the above for 10 additional words.
This worked for me, but only for the word awesome. Weird.
Define function awesome count: (Refer to week one ipython notebook for creating functions and if/then statements)
def awesome_count(x):
if 'awesome' in x:
y=dict['awesome']
else: y=0
return y
The above works. If I call it and look at the head of the dataset the variable awesome is there.
If I do this:
def great_count(x):
if 'great' in x:
y=dict['great']
else: y=0
return y
Then:
products['great'] = products['word_count'].apply(great_count)
I get:
TypeErrorTraceback (most recent call last)
<ipython-input-51-f51e1151a1bd> in <module>()
----> 1 products['great'] = products['word_count'].apply(great_count)
/opt/conda/lib/python2.7/site-packages/graphlab/data_structures/sarray.pyc in apply(self, fn, dtype, skip_undefined, seed)
1868 assert callable(fn), "Input function must be callable."
1869
-> 1870 dryrun = [fn(i) for i in self.head(100) if i is not None]
1871 if dtype == None:
1872 dtype = infer_type_of_list(dryrun)
<ipython-input-50-54d747d1e0e1> in great_count(x)
4 def great_count(x):
5 if 'great' in x:
----> 6 y=dict['great']
7 else: y=0
8 return y
TypeError: 'type' object has no attribute '__getitem__'
By the way, I'm running all this in iPhython Notebook.
来源:https://stackoverflow.com/questions/33506826/call-function-use-apply-in-python