0

I'm trying to iterate over a data frame in python and in my if statement I reference a couple of columns that happen to be a Series. When i run my code I get the following error:

The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

Data:
Taken from solution provided by @CypherX.

template = ['some', 'abra', 'cadabra', 'juju', 'detail page', 'lulu', 'boo', 'honolulu', 'detail page']
prev = ['home', 'abra', 'cacobra', 'juju', 'detail page', 'lulu', 'booboo', 'picabo', 'detail here']
df = pd.DataFrame({'Template': template, 'Prev': prev})
      Template         Prev
0         some         home
1         abra         abra
2      cadabra      cacobra
3         juju         juju
4  detail page  detail page
5         lulu         lulu
6          boo       booboo
7     honolulu       picabo
8  detail page  detail here

My code is the following:

for row in s:
    if (s['Template']=='detail page') and (s['Template']==s['Prev']):
        s['Swipe']=1
    else:
        s['Swipe']=0

where s is my dataframe.

What can I do to fix this? Any ideas?

CypherX
  • 7,019
  • 3
  • 25
  • 37
Ryan Ball
  • 29
  • 3
  • 1
    That's not how iterating a df works. Try `for row in s: print(row)` to see what I mean. For better help, please see [How to make good pandas examples](https://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples) and [edit] your post to provide a [mcve] with sample input and output – G. Anderson Oct 14 '19 at 17:24
  • Okay but I think you understand what I'm trying to do... – Ryan Ball Oct 14 '19 at 17:31
  • Is there any reason why you are using `0` and `1` instead of a boolean? – AMC Oct 30 '19 at 19:10

4 Answers4

2

You could try setting the value of s['Swipe'] using np.where instead:

import numpy as np

s['Swipe'] = np.where((s['Template'] == 'detail page') & (s['Template'] == s['Prev']), 1, 0)
kbfreder
  • 51
  • 7
0

I think it would be something like this:

s['Swipe'] = (s['Template'] == 'detail page') & (s['Template'] == s['Prev'])

You might convert result from boolean to int then, if you need.

Alex
  • 1,118
  • 7
  • 7
0

Since, you did not provide any reproducible problem data, I made my own and here is the solution.

Short Solution

condition = ((df.Template==df.Prev) & (df.Template=='detail page'))
df['Swipe'] = condition.astype(int)

Solution in Detail

Evaluate the condition to a boolean and since you want to assign 1 for True and 0 for False, just a conversion from boolean to int would do the job.

# Prepare Dummy Data
template = ['some', 'abra', 'cadabra', 'juju', 'detail page', 'lulu', 'boo', 'honolulu', 'detail page']
prev = ['home', 'abra', 'cacobra', 'juju', 'detail page', 'lulu', 'booboo', 'picabo', 'detail here']
df = pd.DataFrame({'Template': template, 'Prev': prev})

# Evaluate Condition
condition = ((df.Template==df.Prev) & (df.Template=='detail page'))
df['Swipe'] = condition.astype(int)

print(df)

Output:

      Template         Prev  Swipe
0         some         home      0
1         abra         abra      0
2      cadabra      cacobra      0
3         juju         juju      0
4  detail page  detail page      1
5         lulu         lulu      0
6          boo       booboo      0
7     honolulu       picabo      0
8  detail page  detail here      0

What was the problem in your solution?

  1. Your code iterates over the dataframe s (note: normally s is used for series and df for dataframe), and returns the column names. So the row actually will not return the rows of the dataframe.
  2. Even if you had the row information, you are not using the row anywhere in the code, inside the for loop.
for row in s:
    if (s['Template']=='detail page') and (s['Template']==s['Prev']):
        s['Swipe']=1
    else:
        s['Swipe']=0

I will print out the output with the dataframe df to make my point:

for row in df:
    print(row)

Output:

Template
Prev
Swipe
CypherX
  • 7,019
  • 3
  • 25
  • 37
  • Thank you!! I appreciate the help! – Ryan Ball Oct 14 '19 at 17:56
  • @RyanBall: I added some justification to why your code did not work in the first place. Also, please see how I created a simple reproducible dataframe so anyone could verify the solution quickly. Please make sure to add such reproducible data to your stackoverflow questions whenever possible. Also, please consider **`voting up`** my solution if it helped. – CypherX Oct 14 '19 at 18:07
0

2 quick ways I can think of:

  1. Without using numpy
    s['Swipe'].loc[(s['Template']=='detail page') & (s['Template']==s['Prev'])]=1
    s['Swipe'].loc[(s['Template']!='detail page') | (s['Template']!=s['Prev'])]=0
  1. Using numpy (like how one of the above answers have already specified):
    import numpy as np    
    s['Swipe'] = np.where((s['Template'] == 'detail page') & (s['Template'] == s['Prev']), 1, 0)
san
  • 1,415
  • 8
  • 13