1

I have a dataset of pet names and owners:

Pets    Owners
dog     James
dog     Katelyn
rat     Shelly
cat     Bob

I want to be able to search through the Owners column to find the name Katelyn and then print out a vector names for the given owner. So far I have this:

def pet_name():
    owner = input("What is the Owner name? ")

    # check to see if owner exist in pets dataset
    # if ownderID exist then print corresponding pet names
    if owner in pets['Owners']: 
        print( pets[['Pets','Owners']][pets.Owners == owner])

    # if ownerID doesnt' exist
    elif not age: 
        print("Sorry, this Owner doesn't exist. Try again! ")


    # if no ownerID has been entered at all 
    else: 
        print("You didn't enter any Owner. Try again! ")

When I enter a name to search, it automatically goes to the else portion of the code. How can I fix this? Should I use itterows()?

2 Answers2

0

When checking if owner in pets['Owners'] you are using pets in a dictionary context and it checks if owner is in the index of pets. Instead check if owner in pets['Owners'].values

That said, I'd rather see pet_name written like this:

def pet_name():
    owner = input("What is the Owner name? ")

    # check to see if owner exist in pets dataset
    # if ownderID exist then print corresponding pet names
    mask = pets['Owners'] == owner
    if mask.any():
        print(pets.loc[mask, ['Pets', 'Owners']])

    # if ownerID doesnt' exist
    elif not age: 
        print("Sorry, this Owner doesn't exist. Try again! ")


    # if no ownerID has been entered at all 
    else: 
        print("You didn't enter any Owner. Try again! ")
piRSquared
  • 285,575
  • 57
  • 475
  • 624
  • This worked perfectly! However, I would need it in a vector format ( list/array). So, how can I put it that way? Use list()? – Abdul-Aziz Muhammad May 13 '19 at 22:09
  • I don't know what you mean "I would need it". What is "it"? – piRSquared May 13 '19 at 22:12
  • What operation does 'mask' and 'any()' perform? – Abdul-Aziz Muhammad May 13 '19 at 22:14
  • You should play around with it and see. `mask` is a variable name I set equal to `pets['Owners'] == owner`. It is a `pandas.Series` of boolean dtype. The `any` method of a boolean series returns `True` if any of the values are `True`. I did it this way because I only have to evaluate all the members of the series equal to `owner` one time and then use it in both the evaluation of the `if` statement and in the call to `loc` in order to slice the dataframe. – piRSquared May 13 '19 at 22:17
  • How can get the result to be put in a vector format? as a list? Should I use list()? – Abdul-Aziz Muhammad May 13 '19 at 22:18
  • what is the "result"? You haven't made that clear. `pets.loc[mask, ['Pets', 'Owners']]`? And, what do you mean by "vector format"? I might possibly be able to guess at what you mean but it would be easier if you told me what it is you are trying to return. At the moment, your function doesn't return anything. It only prints stuff. – piRSquared May 13 '19 at 22:19
  • So the result will display the corresponding Pet type along with the Owner. Pets Owner dog Katelyn I would like to some how put this in a vector format. Vector format such as an array. I don't want it to return anything, I just want it to print. – Abdul-Aziz Muhammad May 13 '19 at 22:21
  • So instead of `print(...)` do `return ...` – piRSquared May 13 '19 at 22:22
  • It's [recommended](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.values.html#pandas-series-values) to use `pandas.Series.array` instead of `pandas.Series.values`. Also, could you check out my answer to see if it has any inconsistencies? Thank you. – Amir Shabani May 14 '19 at 13:32
  • 1
    @AmirA.Shabani and for others. As of Pandas version 0.24 the property `array` is available for a Pandas Series object and will return a Pandas array. It will now work for versions prior to that. So for versions >= 0.24 `owner in pets['Owner'].array` will work. As for why it is recommended, I'll have to explore that in more detail. – piRSquared May 14 '19 at 13:47
0

First, let's see what the problem is, then we can find a way to fix it.

In [1]: import pandas as pd

In [2]: pets = pd.read_csv('pets.csv')

In [3]: pets
Out[3]:
  Pets   Owners
0  dog    James
1  dog  Katelyn
2  rat   Shelly
3  cat      Bob

In [4]: type(pets["Owners"])
Out[4]: pandas.core.series.Series

We can see that pets is a pandas.Series object. Now the problem is obviously in this line of code:

if owner in pets['Owners']:

Here's why you can't use in operator with pandas.Series, but basically, it's because the developers of Pandas didn't implement this module in a way that would be possible to use "Membership test operations" like this. Therefore, as you mentioned yourself, this will always return False:

In [5]: owner in pets["Owners"]
Out[5]: False

Now, if you want to use pets["Owners"] you can do it like this (as suggested by @piRSquared):

In [6]: owner in pets["Owners"].values
Out[6]: True

However, if we look at the documentation for pandas.Series.values:

Warning: We recommend using Series.array or Series.to_numpy(), depending on whether you need a reference to the underlying data or a NumPy array.

So we can do it like this:

In [7]: owner in pets["Owners"].array
Out[7]: True

There's also a better way of doing it, you want to find out if "there are any pets for a given owner," correct? If so, you can do it like this:

In [8]: pet = pets.loc[pets["Owners"] == owner, "Pets"]

In [8]: if pet.any():
   ...:     print(pet)
   ...: else:
   ...:     print("You didn't enter any Owner. Try again! ")
Out[8]:
1    dog
Name: Pets, dtype: object

As you can see, this will print a pandas.Series object. You have mentioned that you need it in a "vector/list/array" format. It's a bit unclear, but I think the situation is that an owner can have multiple pets and you want to check if the owner has any pets, and then print all of their pets in a list-type format. If so, you can use pet.array. For example, if we modify your dataset so that Katelyn has more than one pet:

Pets    Owners
dog     James
dog     Katelyn
rat     Katelyn <-----
rat     Shelly
cat     Bob

Then we can see that it gives us a list:

In [9]: if pet.any():
    ...:     print(pet.array)
    ...: else:
    ...:     print("You didn't enter any Owner. Try again! ")
Out[9]: 
<PandasArray>
['dog', 'rat']
Length: 2, dtype: object
Amir Shabani
  • 3,857
  • 6
  • 30
  • 67