Trouble creating new variable based off of existing variable - python

I am trying to create a new variable based off of an existing variable in my df. I have run into this error before and I would like to know what I am doing wrong.
Code:
def DEMO2(a):
if a['DEMO']=='02-05C':
return 'P 02-11'
elif a['DEMO']=='65+M':
return 'P 55-99'
merge_df['DEMO2']=merge_df.apply('DEMO2', axis=1)
TypeError: ("'str' object is not callable", 'occurred at index 0')
I feel like there is an obvious answer that I am missing...

You do not need the DEMO2 function even .
merge_df['DEMO2']=merge_df.DEMO.replace({'02-05C':'P 02-11','65+M':'P 55-99'})

Well you're getting that error because of this
merge_df['DEMO2']=merge_df.apply('DEMO2', axis=1)
Should (probably) be this:
merge_df['DEMO2']=merge_df.apply(DEMO2, axis=1)

Related

Pandas: AttributeError: 'str' object has no attribute 'isnull'

I'm creating a new column named lead_actor_actress_known whose values is boolean based on whether there value in 2nd column lead_actor_actress has value or not. If there is a value(Name of actors) populate 1st column using True if there is no value, return False
AttributeError: 'str' object has no attribute 'isnull'
My code is throwing an error above.
df['lead_actor_actress_known'] = df['lead_actor_actress'].apply(lambda x: True if x.isnull() else False)
What i'm i missing?
Henry Ecker's comment contains the answer to this question, I am reproducing in the answer section for convenience. Replace your application of the .apply() method with the code df['lead_actor_actress_known'] = df['lead_actor_actress'].isna().
The thing to know here is that df['lead_actor_actress'].isna() returns a "Boolean mask" (a series of True and False values) and this is exactly what you are asking to assign the variable lead_actor_actress.

The return of my function is a pandas dataframe object, but I recieve a tuple. What is happening and how can i recieve the object as DataFrame?

I have created a function where I make an pandas DataFrame object, that I place in the return part of the code, when i print type() i get <class 'pandas.core.frame.DataFrame'>, but when i print the type() in the receiving code I get <class 'tuple'>
Is it supposed to be like this or am I doing anything wrong?
Removed Code after i got help and it was answered
The resolve was that I had included a bool statement in addition to the pandas data frame in the return statement
In the receiver code, you may have to change the following ( check the index in e ) -
while True:
c=c+1
e = tl.extractdata(rawlink,c)
if e:
print(type(e[1]),e[1])
The reason is that the extract_data function is actually returning a tuple ( True, horsetable).

Using len() with if/else to populate dataframe variable

I am looking to add a variable to my dataframe that concatenates several other variables. I know that if variable 'do' is less that 4 characters, it is garbage input and I should instead use variable 'ra'. However, the below throws an attribute error: "AttributeError: ("'str' object has no attribute 'len'", 'occurred at index 0')". Is the apply operation the correct way to go about what I'm doing, and if so, how can I correct my function?
def get_combined(row):
if row['do'].len() < 4:
return row['ra']+' '+row['mi']+' '+row['fa']+' '+row['so']
else:
return row['do']+' '+row['mi']+' '+row['fa']+' '+row['so']
df['Combined'] = df.apply(get_combined, axis=1)
The second line should be:
if len(row['do']) < 4:

How do you slice a pandas dataframe as an argument in a function?

What I am looking to do is to put the rules of slicing a pandas dataframe in a function.
For example:
row1 = {'a':5,'b':6,'c':7,'d':'A'}
row2 = {'a':8,'b':9,'c':10,'d':'B'}
row3 = {'a':11,'b':12,'c':13,'d':'C'}
df = pd.DataFrame([row1,row2,row3])
I am slicing the dataframe this way:
print df.loc[df['a']==5]
print df.loc[df['b']==12]
print df.loc[(df['b']==12) | df['d'].isin(['A','C']),'d']
For my purposes, I need to slice the same dataframe in different ways as part of a function. For example:
def slicing(locationargument):
df.loc(locationargument)
do some stuff..
return something
Alternatively, I was expecting getattr() to work but that tells me DataFrames do not have a .loc[...] attribute. For example:
getattr(df,"loc[df['a']==5]")
Returns:
AttributeError: 'DataFrame' object has no attribute 'loc[df['a']==5]'
Am I missing something here? Any thoughts or alternatives would be greatly appreciated!
In Pandas, I believe it's not quite right to think of .loc as a function (or method) on a DataFrame. For example, the syntax df.loc(...) is not right. Instead, you need to write df.loc[...] (brackets, not parentheses).
So how about simply:
def slicing(locationargument):
df.loc[locationargument]
do some stuff..
return something
But then the question becomes "what type of object should locationargument be? If it's an iterable whose length is equal to the number of rows in your data frame, you're all set. An alternative could be to make it a string and then write:
def slicing(locationargumentstring):
df.loc[eval(locationargumentstring)]
do some stuff..
return something
If you go the getattr route, remember that the attribute doesn't include parameters. So the following is bad:
getattr(df, "loc[df['a']==5]")
but the following would work:
getattr(df, "loc")[eval("df['a']==5")]
and, more directly, so would
getattr(df, "loc")[df['a']==5]

"object of type 'NoneType' has no len()" error

I'm seeing weird behavior on this code:
images = dict(cover=[],second_row=[],additional_rows=[])
for pic in pictures:
if len(images['cover']) == 0:
images['cover'] = pic.path_thumb_l
elif len(images['second_row']) < 3:
images['second_row'].append(pic.path_thumb_m)
else:
images['additional_rows'].append(pic.path_thumb_s)
My web2py app gives me this error:
if len(images['cover']) == 0:
TypeError: object of type 'NoneType' has no len()
I can't figure out what's wrong in this. Maybe some scope issue?
You assign something new to images['cover']:
images['cover'] = pic.path_thumb_l
where pic.path_thumb_l is None at some point in your code.
You probably meant to append instead:
images['cover'].append(pic.path_thumb_l)
your problem is that
if len(images['cover']) == 0:
checks the LENGTH of the value of images['cover'] what you meant to do is check if it HAS a value.
do this instead:
if not images['cover']:
The first time you assign: images['cover'] = pic.path_thumb_l, it replaces the value of the empty list initially stored in images['cover'] with the value of pic.path_thumb_l which is None.
Maybe your code in this line must be images['cover'].append(pic.path_thumb_l)
We can also see the type in the same condition, to avoid something if you want, like
if myArray is None:
#Do something when array has no len()
else:
#Do something when array has elements and has len()
In my case I was looking for something in the array, but only if has something, when id does not, was None the type and I need to create it. Hope this works for someones.

Categories

Resources